建立和管理自訂授權方 - AWS IoT Core

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

建立和管理自訂授權方

AWS IoT Core 通過使用授權者資源實現自定義身份驗證和授權方案。每個授權方都包含以下元件:

  • 名稱:識別授權方的唯一使用者定義字串。

  • Lambda 函數 ARN:實作授權和身份驗證邏輯的 Lambda 函數的 Amazon 資源名稱 (ARN)。 

  • 權杖金鑰名稱:用來從HTTP標頭、查詢參數或使用MQTTCONNECT者名稱擷取權杖以執行簽章驗證的金鑰名稱。如果在您的授權方中啟用簽署,則此值為必要的。

  • 已停用簽署旗標 (選用):Boolean 值,指定是否停用認證的簽署需求。 這在簽署認證沒有意義的情況下非常有用,例如使用使用MQTT者名稱和密碼的驗證配置。 預設值為false,因此簽署預設為啟用。

  • 字符簽署公有金鑰: AWS IoT Core 用來驗證字符簽章的公有金鑰。其長度下限為 2,048 位元。如果在您的授權方中啟用簽署,則此值為必要的。 

Lambda 會依據 Lambda 函數執行的次數,以及在您函數中執行程式碼所需的時間,向您收費。如需 Lambda 定價的詳細資訊,請參閱 Lambda 定價。如需建立 Lambda 函數的詳細資訊,請參閱《Lambda 開發人員指南》。

注意

如果將簽署保持啟用狀態,您可以防止無法辨識的用戶端過度觸發 Lambda。在您的授權方中停用簽署之前,請考慮這一點。

注意

自訂授權方的 Lambda 函數逾時限制為 5 秒。

定義您的 Lambda 函數

AWS IoT Core 呼叫授權者時,它會透過包含下列物件的事件觸發與授權者相關聯的 Lambda。JSON示例JSON對象包含所有可能的字段。不包含與連線請求無關的任何欄位。

{     "token" :"aToken",     "signatureVerified": Boolean, // Indicates whether the device gateway has validated the signature.     "protocols": ["tls", "http", "mqtt"], // Indicates which protocols to expect for the request.     "protocolData": {         "tls" : {             "serverName": "serverName" // The server name indication (SNI) host_name string.         },         "http": {             "headers": {                 "#{name}": "#{value}"             },             "queryString": "?#{name}=#{value}"         },         "mqtt": {             "username": "myUserName",             "password": "myPassword", // A base64-encoded string.             "clientId": "myClientId" // Included in the event only when the device sends the value.         }     },     "connectionMetadata": {         "id": UUID // The connection ID. You can use this for logging.     }, }

Lambda 函數應該使用此資訊來驗證傳入連線,並決定連線中允許哪些動作。此函數應該傳送包含下列值的回應。

  • isAuthenticated:指出是否驗證請求的布林值。

  • principalId:英數字串,作為自訂授權請求所傳送之字符的識別符。該值必須為英數字串 (字元數量不低於 1 個且不超過 128 個),且符合此規則表達式 (regex) 模式:([a-zA-Z0-9]){1,128}。不是英數字元的特殊字元不允許與 principalId in 搭配使用 AWS IoT Core。如果允許使用非英數字元的特殊字元,請參閱其他 AWS 服務的文件principalId

  • policyDocuments:JSON格式化的 AWS IoT Core 政策文件清單如需有關建立 AWS IoT Core 策略的更多資訊,請參閱AWS IoT Core 政策。政策文件的數目上限為 10 份政策文件。每份政策文件最多可包含 2,048 個字元。

  • disconnectAfterInSeconds:整數,用來指定連接至 AWS IoT Core 閘道的持續時間上限 (以秒為單位)。最小值為 300 秒,最大值為 86,400 秒。預設值為 86,400。

    注意

    的值 disconnectAfterInSeconds (由 Lambda 函數傳回) 會在連線建立時設定。在後續的政策重新整理 Lambda 呼叫期間,無法修改此值。

  • refreshAfterInSeconds:整數,用來指定政策重新整理的間隔。一旦超出此間隔, AWS IoT Core 便會叫用 Lambda 函數,以允許政策重新整理。最小值為 300 秒,最大值為 86,400 秒。

 下列JSON物件包含 Lambda 函數可傳送的回應範例。

{ "isAuthenticated":true, //A Boolean that determines whether client can connect. "principalId": "xxxxxxxx",  //A string that identifies the connection in logs. "disconnectAfterInSeconds": 86400,  "refreshAfterInSeconds": 300,   "policyDocuments": [       {         "Version": "2012-10-17",         "Statement": [            {               "Action": "iot:Publish",               "Effect": "Allow",               "Resource": "arn:aws:iot:us-east-1:<your_aws_account_id>:topic/customauthtesting"             }          ]        }     ] }

policyDocument值必須包含有效的 AWS IoT Core 政策文件。如需有關 AWS IoT Core 策略的詳細資訊,請參閱AWS IoT Core 政策。 MQTT在單次連線TLS和反MQTT覆 WebSockets連線中,會根據refreshAfterInSeconds欄位值中指定的間隔 AWS IoT Core 快取此原則。在HTTP連線的情況下,除非您的裝置使用HTTP持續性連線 (也稱為 HTTP keep-alive 或HTTP連線重複使用),否則每個授權請求都會呼叫 Lambda 函數,您可以在設定授權者時選擇啟用快取。在此間隔期間,會針對此快取政策 AWS IoT Core 授權已建立連線中的動作,而不會再次觸發 Lambda 函數。如果在自訂驗證期間發生失敗,則會 AWS IoT Core 終止連線。 AWS IoT Core 如果連線的開啟時間超過disconnectAfterInSeconds參數中指定的值,也會終止連線。

下列範例 JavaScript 包含 Node.js Lambda 函數範例,該函數會在 MQTT Connect 訊息中尋找值為的密碼,test並傳回原則,該原則會授 AWS IoT Core 與名為的用戶端連線myClientName並發佈至包含相同用戶端名稱的主題的權限。如果找不到預期的密碼,它會傳回拒絕這兩個動作的政策。

// A simple Lambda function for an authorizer. It demonstrates // how to parse an MQTT password and generate a response. exports.handler = function(event, context, callback) {     var uname = event.protocolData.mqtt.username;     var pwd = event.protocolData.mqtt.password;     var buff = new Buffer(pwd, 'base64');     var passwd = buff.toString('ascii');     switch (passwd) {         case 'test':             callback(null, generateAuthResponse(passwd, 'Allow')); break;         default:             callback(null, generateAuthResponse(passwd, 'Deny'));       } }; // Helper function to generate the authorization response. var generateAuthResponse = function(token, effect) { var authResponse = {}; authResponse.isAuthenticated = true; authResponse.principalId = 'TEST123'; var policyDocument = {}; policyDocument.Version = '2012-10-17'; policyDocument.Statement = []; var publishStatement = {}; var connectStatement = {}; connectStatement.Action = ["iot:Connect"]; connectStatement.Effect = effect; connectStatement.Resource = ["arn:aws:iot:us-east-1:123456789012:client/myClientName"]; publishStatement.Action = ["iot:Publish"]; publishStatement.Effect = effect; publishStatement.Resource = ["arn:aws:iot:us-east-1:123456789012:topic/telemetry/myClientName"]; policyDocument.Statement[0] = connectStatement; policyDocument.Statement[1] = publishStatement; authResponse.policyDocuments = [policyDocument]; authResponse.disconnectAfterInSeconds = 3600; authResponse.refreshAfterInSeconds = 300; return authResponse; }

前述 Lambda 函數test在 MQTT Connect 訊息中收到預期的密碼JSON時,會傳回下列項目。passwordprincipalId內容的值將是來自「MQTTConnect」訊息的值。

{ "password": "password", "isAuthenticated": true, "principalId": "principalId", "policyDocuments": [ { "Version": "2012-10-17", "Statement": [ { "Action": "iot:Connect", "Effect": "Allow", "Resource": "*" }, { "Action": "iot:Publish", "Effect": "Allow", "Resource": "arn:aws:iot:region:accountId:topic/telemetry/${iot:ClientId}" }, { "Action": "iot:Subscribe", "Effect": "Allow", "Resource": "arn:aws:iot:region:accountId:topicfilter/telemetry/${iot:ClientId}" }, { "Action": "iot:Receive", "Effect": "Allow", "Resource": "arn:aws:iot:region:accountId:topic/telemetry/${iot:ClientId}" } ] } ], "disconnectAfterInSeconds": 3600, "refreshAfterInSeconds": 300 }

建立授權方

您可以使用建立授權者。CreateAuthorizerAPI 下列範例說明命令。

aws iot create-authorizer --authorizer-name MyAuthorizer --authorizer-function-arn arn:aws:lambda:us-west-2:<account_id>:function:MyAuthorizerFunction  //The ARN of the Lambda function. [--token-key-name MyAuthorizerToken //The key used to extract the token from headers. [--token-signing-public-keys FirstKey= "-----BEGIN PUBLIC KEY-----   [...insert your public key here...]   -----END PUBLIC KEY-----" [--status ACTIVE] [--tags <value>] [--signing-disabled | --no-signing-disabled]

您可以使用 signing-disabled 參數,在每次叫用授權方時選擇退出簽章驗證。除非您必須停用簽署,否則強烈建議您不要這樣做。簽章驗證可保護您防範未知裝置過度叫用 Lambda 函數。在建立授權方之後,您無法更新授權方的 signing-disabled 狀態。若要變更此行為,您必須使用不同的 signing-disabled 參數值建立另一個自訂授權方。

如果您已停用簽署,tokenKeyNametokenSigningPublicKeys 參數的值是選用值。如果啟用簽署,則它們是必要值。

建立 Lambda 函數和自訂授權者之後,您必須明確授與 AWS IoT Core 服務權限,以代表您叫用該函數。 您可以使用以下命令執行此操作。

aws lambda add-permission --function-name <lambda_function_name> --principal iot.amazonaws.com --source-arn <authorizer_arn> --statement-id Id-123 --action "lambda:InvokeFunction"

測試您的授權方

您可以使用TestInvokeAuthorizerAPI來測試授權者的呼叫和傳回值。 這API可讓您指定通訊協定中繼資料,並在授權者中測試簽名驗證。  

下列索引標籤顯示如何使用 AWS CLI 來測試授權者。

Unix-like
aws iot test-invoke-authorizer --authorizer-name NAME_OF_AUTHORIZER \ --token TOKEN_VALUE --token-signature TOKEN_SIGNATURE
Windows CMD
aws iot test-invoke-authorizer --authorizer-name NAME_OF_AUTHORIZER ^ --token TOKEN_VALUE --token-signature TOKEN_SIGNATURE
Windows PowerShell
aws iot test-invoke-authorizer --authorizer-name NAME_OF_AUTHORIZER ` --token TOKEN_VALUE --token-signature TOKEN_SIGNATURE

token-signature 參數的值是簽署的字符。若要了解如何取得此值,請參閱 簽署字符

如果您的授權方取得使用者名稱和密碼,您可以使用 --mqtt-context 參數來傳遞此資訊。下列索引標籤說明如何使用TestInvokeAuthorizerAPI將包含使用者名稱、密碼和用戶端名稱的JSON物件傳送給您的自訂授權者。

Unix-like
aws iot test-invoke-authorizer --authorizer-name NAME_OF_AUTHORIZER \ --mqtt-context '{"username": "USER_NAME", "password": "dGVzdA==", "clientId":"CLIENT_NAME"}'
Windows CMD
aws iot test-invoke-authorizer --authorizer-name NAME_OF_AUTHORIZER ^ --mqtt-context '{"username": "USER_NAME", "password": "dGVzdA==", "clientId":"CLIENT_NAME"}'
Windows PowerShell
aws iot test-invoke-authorizer --authorizer-name NAME_OF_AUTHORIZER ` --mqtt-context '{"username": "USER_NAME", "password": "dGVzdA==", "clientId":"CLIENT_NAME"}'

密碼必須為 base64 編碼。下列範例顯示如何在類似 Unix 環境中編碼密碼。

echo -n PASSWORD | base64

管理自訂授權方

您可以使用以下APIs方法管理您的授權者。

  • ListAuthorizers:顯示您帳戶中的所有授權者。

  • DescribeAuthorizer:顯示指定授權者的特性。這些值包括建立日期、上次修改日期和其他屬性。

  • SetDefaultAuthorizer:指定資 AWS IoT Core 料端點的預設授權者。 AWS IoT Core 如果裝置未傳遞 AWS IoT Core 認證且未指定授權者,則會使用此授權者。如需使用 AWS IoT Core 認證的詳細資訊,請參閱用戶端身分驗證

  • UpdateAuthorizer:變更指定授權者的狀態、權杖金鑰名稱或公開金鑰。

  • DeleteAuthorizer:刪除指定的授權者。

注意

您無法更新授權方的簽署需求。這表示您無法在需要簽署的現有授權方中停用簽署。您也無法在不需要簽署的現有授權方中要求簽署。