カスタム認証チャレンジの Lambda トリガー
Amazon Cognito ユーザープールの認証フローを構築した後で、組み込みフローを超えた認証モデルに拡張したい場合があります。カスタムチャレンジトリガーの一般的なユースケースの 1 つは、ユーザー名、パスワード、および多要素認証 (MFA) を超えた追加のセキュリティチェックを実装することです。カスタムチャレンジは、Lambda がサポートするプログラミング言語で生成できる質問とレスポンスです。例えば、認証を許可する前に、CAPTCHA を解決することや、セキュリティの質問に回答することをユーザーに要求する場合があります。もう 1 つの潜在的なニーズは、特殊な認証要素やデバイスと統合することです。または、ハードウェアセキュリティキーまたは生体認証デバイスでユーザーを認証するソフトウェアを開発済みである場合もあります。カスタムチャレンジの認証成功の定義は、どのような回答であっても、Lambda 関数が正しいものとして受け入れる回答です。例えば、固定文字列、または外部 API からの十分なレスポンスです。
カスタムチャレンジを使用した認証を開始して認証プロセスを完全に制御することも、アプリケーションがカスタムチャレンジを受信する前にユーザー名パスワード認証を実行することもできます。
カスタム認証チャレンジの Lambda トリガー
これらの 3 つの Lambda 関数は連鎖して、完全に制御範囲内で独自の設計の認証メカニズムを提示します。カスタム認証は、クライアントと Lambda 関数にアプリケーションロジックを必要とするため、マネージドログイン内ではカスタム認証を処理できません。この認証システムには、デベロッパーの労力が追加で必要です。アプリケーションは、ユーザープール API を使用して認証フローを実行し、結果として返されるチャレンジを、カスタム構築されたログインインターフェイスで処理する必要があります。このインターフェイスは、カスタム認証チャレンジの中心に質問を表示します。
カスタム認証の実装の詳細については、「カスタム認証フローとチャレンジ」を参照してください。
API オペレーション InitiateAuth または AdminInitiateAuth と RespondToAuthChallenge または AdminRespondToAuthChallenge 間の認証。このフローでは、認証が失敗するか、トークンが発行されるまで、ユーザーは引き続きチャレンジに回答して認証を行います。チャレンジレスポンスが新しいチャレンジとなる場合があります。この場合、アプリケーションは新しいチャレンジに対して必要な回数を応答します。認証は、認証チャレンジの定義関数がそれまでの結果を分析し、すべてのチャレンジが回答されたと判断し、IssueTokens を返すときに完了します。
カスタムチャレンジフローでの SRP 認証
Amazon Cognito では、カスタムチャレンジを発行する前にユーザーパスワードを検証させることができます。リクエストレートクォータの認証カテゴリに関連付けられているすべての Lambda トリガーは、カスタムチャレンジフローで SRP 認証を行うと、実行されます。以下は、そのプロセスの概要です。
-
アプリは、
AuthParametersマップを使用してInitiateAuthまたはAdminInitiateAuthを呼び出してサインインを開始します。パラメータにはCHALLENGE_NAME: SRP_A,、SRP_AおよびUSERNAMEの値を含める必要があります。 -
Amazon Cognito は、
challengeName: SRP_AとchallengeResult: trueを含む初期セッションで、認証チャレンジの定義 Lambda トリガーを呼び出します。 -
Lambda 関数は、これらの入力を受け取った後、
challengeName: PASSWORD_VERIFIER、issueTokens: false、failAuthentication: falseで応答します。 -
パスワードの検証が成功すると、Amazon Cognito
challengeName: PASSWORD_VERIFIERとchallengeResult: trueが含まれる新しいセッションで Lambda 関数を再度呼び出します。 -
カスタムチャレンジを開始するために、Lambda 関数は
challengeName: CUSTOM_CHALLENGE、issueTokens: false、およびfailAuthentication: falseで応答します。パスワード検証でカスタム認証フローを開始したくない場合は、CHALLENGE_NAME: CUSTOM_CHALLENGEを含むAuthParametersマップでサインインを開始できます。 -
チャレンジループは、すべてのチャレンジが回答されるまで繰り返します。
以下は、SRP フローによるカスタム認証の前になされる開始 InitiateAuth リクエストの例です。
{ "AuthFlow": "CUSTOM_AUTH", "ClientId": "1example23456789", "AuthParameters": { "CHALLENGE_NAME": "SRP_A", "USERNAME": "testuser", "SRP_A": "[SRP_A]", "SECRET_HASH": "[secret hash]" } }
カスタム認証 SRP フローでのパスワードのリセット
ユーザーが FORCE_CHANGE_PASSWORD ステータスの場合、カスタム認証フローは、認証チャレンジの整合性を維持しながら、パスワード変更ステップを統合する必要があります。Amazon Cognito は、NEW_PASSWORD_REQUIRED チャレンジ中に [認証チャレンジを定義] Lambda トリガーを呼び出します。このシナリオの場合、ユーザーがカスタムチャレンジフローと SRP 認証を使用してサインインするときに、パスワードのリセット状態にあれば、新しいパスワードを設定できます。
ユーザーは、RESET_REQUIRED ステータスまたは FORCE_CHANGE_PASSWORD ステータスである場合、NEW_PASSWORD を使用して NEW_PASSWORD_REQUIRED チャレンジに応答する必要があります。SRP を使用したカスタム認証の場合、ユーザーが SRP NEW_PASSWORD_REQUIRED チャレンジを完了すると、Amazon Cognito は PASSWORD_VERIFIER チャレンジを返します。認証チャレンジ定義トリガーは、両方のチャレンジ結果を session 配列で受け取り、ユーザーがパスワードを正常に変更した後で、追加のカスタムチャレンジを続行できます。
認証チャレンジ定義の Lambda トリガーは、SRP 認証、パスワードリセット、以降のカスタムチャレンジを通じて、チャレンジシーケンスを管理する必要があります。トリガーは、完了したチャレンジの配列 (PASSWORD_VERIFIER と NEW_PASSWORD_REQUIRED の両方の結果を含む) を session パラメータで受け取ります。実装の例については、「認証チャレンジの定義の例」を参照してください。
認証フローの手順
ユーザーがカスタムチャレンジの前にパスワードを検証する必要がある場合は、次の手順に従います。
-
アプリは、
AuthParametersマップを使用してInitiateAuthまたはAdminInitiateAuthを呼び出してサインインを開始します。パラメータにはCHALLENGE_NAME: SRP_Aに加えて、SRP_AとUSERNAMEの値を含める必要があります。 -
Amazon Cognito は、
challengeName: SRP_AとchallengeResult: trueを含む初期セッションで、認証チャレンジの定義 Lambda トリガーを呼び出します。 -
Lambda 関数は、これらの入力を受け取った後、
challengeName: PASSWORD_VERIFIER、issueTokens: false、failAuthentication: falseで応答します。 -
パスワードの検証が成功すると、次の 2 つのどちらかになります。
- 通常ステータスのユーザーの場合:
-
Amazon Cognito は、
challengeName: PASSWORD_VERIFIERとchallengeResult: trueを含む新しいセッションで Lambda 関数を再度呼び出します。カスタムチャレンジを開始するために、Lambda 関数は
challengeName: CUSTOM_CHALLENGE、issueTokens: false、およびfailAuthentication: falseで応答します。 RESET_REQUIREDステータスまたはFORCE_CHANGE_PASSWORDステータスのユーザーの場合:-
Amazon Cognito は、
challengeName: PASSWORD_VERIFIERとchallengeResult: trueを含むセッションで Lambda 関数を呼び出します。Lambda 関数は、
challengeName: NEW_PASSWORD_REQUIRED、issueTokens: false、およびfailAuthentication: falseにより、これに応答する必要があります。パスワードが正常に変更されると、Amazon Cognito は
PASSWORD_VERIFIERとNEW_PASSWORD_REQUIREDの両方の結果を含むセッションで Lambda 関数を呼び出します。カスタムチャレンジを開始するために、Lambda 関数は
challengeName: CUSTOM_CHALLENGE、issueTokens: false、およびfailAuthentication: falseで応答します。
-
チャレンジループは、すべてのチャレンジが回答されるまで繰り返します。
パスワード検証でカスタム認証フローを開始したくない場合は、CHALLENGE_NAME: CUSTOM_CHALLENGE を含む AuthParameters マップでサインインを開始できます。
セッション管理
認証フローは、一連のセッション ID とチャレンジ結果を通じてセッションの継続性を維持します。チャレンジレスポンスごとに新しいセッション ID を生成して、セッション再利用エラーを防ぎます。これは、多要素認証フローでは特に重要です。
チャレンジの結果は、Lambda トリガーが受信するセッション配列に時系列で保存されます。FORCE_CHANGE_PASSWORD ステータスのユーザーの場合、セッション配列には以下が含まれます。
session[0]- 最初のSRP_Aチャレンジsession[1]-PASSWORD_VERIFIERの結果session[2]-NEW_PASSWORD_REQUIREDの結果後続の要素 - 追加のカスタムチャレンジの結果
認証フローの例
次の例は、パスワード変更とカスタム CAPTCHA チャレンジの両方を完了する必要があるユーザー (FORCE_CHANGE_PASSWORD ステータス) の完全なカスタム認証フローを示しています。
-
InitiateAuth リクエスト
{ "AuthFlow": "CUSTOM_AUTH", "ClientId": "1example23456789", "AuthParameters": { "CHALLENGE_NAME": "SRP_A", "USERNAME": "testuser", "SRP_A": "[SRP_A]" } } -
InitiateAuth レスポンス
{ "ChallengeName": "PASSWORD_VERIFIER", "ChallengeParameters": { "USER_ID_FOR_SRP": "testuser" }, "Session": "[session_id_1]" } -
PASSWORD_VERIFIERを使用した RespondToAuthChallenge リクエスト{ "ChallengeName": "PASSWORD_VERIFIER", "ClientId": "1example23456789", "ChallengeResponses": { "PASSWORD_CLAIM_SIGNATURE": "[claim_signature]", "PASSWORD_CLAIM_SECRET_BLOCK": "[secret_block]", "TIMESTAMP": "[timestamp]", "USERNAME": "testuser" }, "Session": "[session_id_1]" } -
NEW_PASSWORD_REQUIREDチャレンジを使用した RespondToAuthChallenge レスポンス{ "ChallengeName": "NEW_PASSWORD_REQUIRED", "ChallengeParameters": {}, "Session": "[session_id_2]" } -
NEW_PASSWORD_REQUIREDを使用した RespondToAuthChallenge リクエスト{ "ChallengeName": "NEW_PASSWORD_REQUIRED", "ClientId": "1example23456789", "ChallengeResponses": { "NEW_PASSWORD": "[password]", "USERNAME": "testuser" }, "Session": "[session_id_2]" } -
CAPTCHA カスタムチャレンジを使用した RespondToAuthChallenge レスポンス
{ "ChallengeName": "CUSTOM_CHALLENGE", "ChallengeParameters": { "captchaUrl": "url/123.jpg" }, "Session": "[session_id_3]" } -
CAPTCHA カスタムチャレンジを使用した RespondToAuthChallenge リクエスト
{ "ChallengeName": "CUSTOM_CHALLENGE", "ClientId": "1example23456789", "ChallengeResponses": { "ANSWER": "123", "USERNAME": "testuser" }, "Session": "[session_id_3]" }
6. 最終的な成功レスポンス
{ "AuthenticationResult": { "AccessToken": "eyJra456defEXAMPLE", "ExpiresIn": 3600, "IdToken": "eyJra789ghiEXAMPLE", "RefreshToken": "eyJjd123abcEXAMPLE", "TokenType": "Bearer" }, "ChallengeParameters": {} }