カスタムオーソライザーの作成と管理 - 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 がオーソライザーを呼び出すと、オーソライザーに関連付けられた 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の では使用できません 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 over TLS および MQTT over WebSockets Connections では、 は refreshAfterInSecondsフィールドの値で指定された間隔でこのポリシーを AWS IoT Core キャッシュします。HTTP 接続の場合、オーソライザーの設定時に選択するとキャッシュを有効にできる HTTP 持続的接続 (HTTP キープアライブまたは HTTP 接続の再利用とも呼ばれる) をデバイスで使用していない限り、認証リクエストごとに Lambda 関数が呼び出されます。この間隔で、 は Lambda 関数を再度トリガーすることなく、このキャッシュされたポリシーに対して確立された接続のアクション AWS IoT Core を承認します。カスタム認証中に障害が発生すると、 は接続を AWS IoT Core 終了します。 AWS IoT Core また、 disconnectAfterInSecondsパラメータで指定された値よりも長く開いている場合は、接続も終了します。

以下に、 の値を持つ MQTT Connect メッセージでパスワードを検索testし、 という名前のクライアント AWS IoT Core と接続myClientNameし、同じクライアント名を含むトピックに発行するアクセス許可を付与するポリシーを返すサンプル Node.js Lambda 関数 JavaScript を示します。想定されるパスワードが見つからない場合、これらの 2 つのアクションを拒否するポリシーを返します。

// 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 を返します。password プロパティと principalId プロパティの値は、MQTT Connect メッセージの値です。

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

オーソライザーを作成する

CreateAuthorizer API を使用してオーソライザーを作成できます。次の例では、 コマンドについて説明します。

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 パラメータの異なる値を持つ別のカスタムオーソライザーを作成する必要があります。

署名を無効にしている場合、tokenKeyName パラメータと tokenSigningPublicKeys パラメータの値はオプションです。署名が有効になっている場合、これらは必須の値です。

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: 指定されたオーソライザーを削除します。

注記

オーソライザーの署名要件を更新することはできません。これは、署名を必要とする既存のオーソライザーでの署名を無効にすることはできないことを意味します。また、署名を必要としない既存のオーソライザーで署名を要求することもできません。