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

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

建立和管理自訂授權方

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

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

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

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

  • 已停用簽署旗標 (選用):布林值,用來指定是否要停用憑證上的簽署需求。 這對於簽署憑證沒有意義的案例很有用,例如使用 MQTT 使用者名稱和密碼的身分驗證結構述。預設值為 false,因此預設會啟用簽署。

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

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

注意

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

注意

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

定義您的 Lambda 函數

AWS IoT Core 呼叫授權者時,它會透過包含下列 JSON 物件的事件觸發與授權者相關聯的 Lambda。範例 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 政策。 在透過 TLS 和 MQTT 透過 WebSockets連線的 MQTT 中,按欄位值中指定的間隔 AWS IoT Core 快取此原則。refreshAfterInSeconds如果採用 HTTP 連線,除非裝置使用的是 HTTP 持續連線 (也稱為 HTTP 保持連線或 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 函數在 MQTT Connect 訊息中收到 test 的預期密碼時,它會傳回下列 JSON。passwordprincipalId 屬性的值會是 MQTT 連結訊息的值。

{ "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"

測試您的授權方

您可以使用TestInvoke授權者 API 來測試授權者的調用和返回值。 此 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 參數來傳遞此資訊。下列標籤顯示如何使用 TestInvokeAuthorizer API,將包含使用者名稱、密碼和用戶端名稱的 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

管理自訂授權方

您可以使用下列 API 來管理授權方。

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

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

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

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

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

注意

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