ユーザープール認証フロー - Amazon Cognito

ユーザープール認証フロー

Amazon Cognito には、ユーザーを認証する方法がいくつか用意されています。ドメインの有無にかかわらず、すべてのユーザープールはユーザープール API でユーザーを認証できます。ユーザープールにドメインを追加すると、ユーザープール エンドポイントを使用できます。ユーザープール API は、API リクエストのさまざまな認可モデルとリクエストフローをサポートします。

ユーザーのアイデンティティを検証するため、Amazon Cognito では、パスワードの他にも新しいタイプのチャレンジが導入されています。Amazon Cognito 認証では、通常、次の順序で 2 つの API オペレーションを実装する必要があります。

Public authentication

InitiateAuth および RespondToAuthChallenge は、クライアント側のパブリックアプリケーションクライアントで使用する認証されていない API です。

Server-side authentication

AdminInitiateAuth および AdminRespondToAuthChallenge は IAM 認証情報を必要とし、サーバー側の機密アプリクライアントに適しています。

認証が失敗するか、Amazon Cognito がユーザーにトークンを発行するまで、ユーザーは連続してチャレンジに回答して認証を進めます。カスタム認証フローをサポートするために、さまざまなチャレンジを含むプロセスで Amazon Cognito でこれらの手順を繰り返すことができます。

Authentication flow diagram showing user, mobile/web app, and user pool interactions for token issuance.

通常、アプリケーションはプロンプトを表示してユーザーから情報を収集し、その情報を API リクエストで Amazon Cognito に送信します。ユーザープールでの InitiateAuth フローを考えてみます。このユーザープールには、多要素認証 (MFA) を使用してユーザーを設定済みです。

  1. アプリケーションは、ユーザーにユーザー名とパスワードの入力を求めます。

  2. ユーザー名とパスワードをパラメータとして InitiateAuth に含めます。

  3. Amazon Cognito から SMS_MFA チャレンジとセッション識別子が返されます。

  4. アプリケーションは、ユーザーにスマートフォンの MFA コードの入力を求めます。

  5. そのコードとセッション ID を RespondToAuthChallenge リクエストに含めます。

ユーザープールの機能によっては、アプリケーションが Amazon Cognito からトークンを取得する前に、InitiateAuth へのいくつかのチャレンジに対応することが必要になります。Amazon Cognito は、各リクエストへの応答にセッション文字列を含めます。API リクエストを 1 つの認証フローにまとめるには、前のリクエストに対する応答のセッション文字列を、後続の各リクエストに含めます。デフォルトでは、セッション文字列が期限切れになる前に、ユーザーに各チャレンジを完了するまでに 3 分間が与えられます。この期間を調整するには、アプリケーションクライアントの認証フローセッション持続期間を変更します。次の手順では、アプリクライアントの構成で、この設定を変更する方法について説明します。

注記

認証フローセッション期間の設定は、Amazon Cognito ユーザープール API による認証に適用されます。Amazon Cognito がホストする UI では、多要素認証の場合はセッション時間を 3 分、パスワードリセットコードの場合は 8 分に設定しています。

Amazon Cognito console
アプリクライアントの認証フローセッション持続期間を設定するには (AWS Management Console)
  1. ユーザープールの [App integration] (アプリの統合) タブで、[App clients and analytics] (アプリクライアントと分析) コンテナからアプリクライアントの名前を選択します。

  2. [アプリケーションクライアントに関する情報] コンテナで [編集] を選択します。

  3. [Authentication flow session duration] (認証フローセッション持続期間) の値を、SMS MFA コードに必要な有効持続期間 (分単位) に変更します。これにより、ユーザーがアプリクライアントで認証チャレンジを完了するまでの時間も変更されます。

  4. [Save changes] (変更の保存) をクリックします。

Amazon Cognito API
アプリクライアントの認証フローセッション持続期間を設定するには (Amazon Cognito API)
  1. DescribeUserPoolClient リクエストから既存のユーザープール設定を使用して UpdateUserPoolClient リクエストを準備します。UpdateUserPoolClient リクエストには、既存のアプリクライアントのプロパティをすべて含める必要があります。

  2. AuthSessionValidity の値を、SMS MFA コードに必要な有効持続期間 (分単位) に変更します。これにより、ユーザーがアプリクライアントで認証チャレンジを完了するまでの時間も変更されます。

アプリクライアントの詳細については、「アプリケーションクライアントによるアプリケーション固有の設定」を参照してください。

AWS Lambda トリガーを使用して、ユーザーの認証方法をカスタマイズします。トリガーは独自のチャレンジを認証フローの一部として発行し検証を行います。

また、安全なバックエンドサーバーでは、管理者の認証フローを使用することもできます。ユーザー移行の認証フローを使用すると、ユーザーがパスワードをリセットしなくてもユーザー移行できます。

サインインの試行の失敗に対する、Amazon Cognito ロックアウト動作

認証されていないか、または IAM 認証でのサインインに 5 回失敗すると、Amazon Cognito はユーザーを 1 秒間ロックアウトします。ロックアウトの期間は、試行が 1 回失敗するたびに 2 倍になり、最大で約 15 分になります。ロックアウト期間中に試行すると Password attempts exceeded 例外が生成され、その後のロックアウト期間の長さには影響しません。サインイン試行の累積失敗回数 n (Password attempts exceeded 例外を含まない) に対して、Amazon Cognito はユーザーを 2^(n-5) 秒間ロックアウトします。ロックアウトを n=0 初期状態にリセットするには、ユーザーは、ロックアウト期間後にサインインに成功するか、連続 15 分間、サインイン試行を開始してはなりません。この動作は変更される可能性があります。この動作は、パスワードベースの認証も実行しない限り、カスタムチャレンジに適用されません。

クライアント側の認証フロー

AWS Amplify または AWS SDK で作成したユーザークライアント側のアプリケーションの場合、以下の手順で動作します。

  1. ユーザーがアプリにユーザー名とパスワードを入力します。

  2. アプリケーションが、ユーザーのユーザー名と SRP (Secure Remote Password) 詳細を使用して、InitiateAuth オペレーションを呼び出します。

    この API オペレーションは、認証のパラメータを返します。

    注記

    アプリは、AWS SDK に組み込まれている Amazon Cognito SRP 機能を使用して SRP の詳細を生成します。

  3. アプリが RespondToAuthChallenge 操作を呼び出します。呼び出しが成功すると、Amazon Cognito からユーザーのトークンが返され、認証フローが完了します。

    Amazon Cognito に必要なチャレンジが別に存在する場合は、RespondToAuthChallenge を呼び出してもトークンは返されません。代わりに、呼び出しによってセッションが返されます。

  4. RespondToAuthChallenge からセッションが返された場合、アプリは RespondToAuthChallenge を再度呼び出します。今回の呼び出しには、セッションとチャレンジのレスポンス (MFA コードなど) が使用されます。

サーバー側の認証フロー

ユーザーアプリがなく、その代わりに Java、Ruby、Node.js のセキュアバックエンド、またはサーバー側のアプリを使用する場合は、Amazon Cognito ユーザープールの認証済みのサーバー側 API を使用できます。

サーバー側のアプリでのユーザープール認証は、クライアント側のアプリでの認証に似ています。次の点が異なります。

  • サーバー側のアプリは、InitiateAuth の代わりに AdminInitiateAuth API 操作を呼び出します。このオペレーションには、cognito-idp:AdminInitiateAuth および cognito-idp:AdminRespondToAuthChallenge を含むアクセス許可を持つ AWS 認証情報が必要です。オペレーションからは、必要な認証パラメータが返されます。

  • サーバー側のアプリに認証パラメータが設定された後に、AdminRespondToAuthChallenge API オペレーションが (RespondToAuthChallenge の代わりに) 呼び出されます。AdminRespondToAuthChallenge API オペレーションは、AWS の認証情報を指定した場合のみ成功します。

AWS 認証情報での Amazon Cognito API リクエストへの署名の詳細については、「AWS 全般的なリファレンス」の「署名バージョン 4 の署名プロセス」を参照してください。

AdminInitiateAuth および AdminRespondToAuthChallenge の API オペレーションでは、ユーザーネームとパスワードのユーザー認証情報を管理者のログインに使用することを許可しません。ただし、以下のいずれかの方法で、明示的にユーザー認証情報を使用可能にした場合を除きます。

  • CreateUserPoolClient または UpdateUserPoolClient を呼び出すときは、ExplicitAuthFlow パラメータに ALLOW_ADMIN_USER_PASSWORD_AUTH (以前は ADMIN_NO_SRP_AUTH と呼ばれています) を含めます。

  • アプリクライアントの認証フローのリストに ALLOW_ADMIN_USER_PASSWORD_AUTH を追加します。ユーザープールの [App integration] (アプリ統合) タブの [App clients and analytics] (アプリクライアントと分析) でアプリクライアントを設定します。詳細については、「アプリケーションクライアントによるアプリケーション固有の設定」を参照してください。

カスタム認証フロー

Amazon Cognito ユーザープールにより、カスタム認証フローを使用することもできます。これは AWS Lambda トリガーを使用したチャレンジ/レスポンスベースの認証モデルの作成に役立ちます。

カスタム認証フローを使用すると、チャレンジとレスポンスサイクルをカスタマイズすることが可能になり、さまざまな要件に対応できます。このフローは、使用する認証のタイプを示す InitiateAuth API 操作の呼び出しから始まり、初期の認証パラメータを提供します。Amazon Cognito は、以下のいずれかの情報を使用して InitiateAuth コールに応答します。

  • ユーザーへのチャレンジ、ならびにセッションおよびパラメータ。

  • ユーザーが認証に失敗した場合はエラー。

  • InitiateAuth コールで渡されたパラメータがユーザーのサインインに十分な場合は、ID、アクセス権限、更新トークン。(通常、ユーザーまたはアプリケーションは最初にチャレンジに応答する必要がありますが、カスタムコードはこれを判定する必要があります。)

Amazon Cognito がチャレンジで InitiateAuth コールに応答する場合、アプリは追加の入力を収集して、RespondToAuthChallenge 操作を呼び出します。このコールは、チャレンジ応答を提供し、セッションを返します。Amazon Cognito は、RespondToAuthChallenge コールに対しても InitiateAuth コール同様の対応をします。ユーザーがサインインしている場合、Amazon Cognito はトークンを提供します。ユーザーがサインインしていない場合、Amazon Cognito は別のチャレンジまたはエラーを提供します。Amazon Cognito が別のチャレンジを返した場合、ユーザーが正常にサインインするかエラーが返されるまで、シーケンスが繰り返され、アプリは RespondToAuthChallenge を呼び出します。InitiateAuth API 操作と RespondToAuthChallenge API 操作に関する詳細については、API ドキュメントに記載されています。

組み込みの認証フローとチャレンジ

Amazon Cognito には、SRP (Secure Remote Password) プロトコルを通じてユーザー名とパスワードを検証する標準的な認証フロー用として、AuthFlow 値と ChallengeName 値が組み込まれています。AWS SDK には、Amazon Cognito を使用したこれらのフローのサポートが組み込まれています。

フローは USER_SRP_AUTHAuthFlow として InitiateAuth に送信することから始まります。また、AuthParametersUSERNAME および SRP_A の値を送信します。InitiateAuth コールが成功した時点で、レスポンスのチャレンジパラメータには PASSWORD_VERIFIERChallengeName および SRP_B として含められています。次に、アプリは RespondToAuthChallenge を呼び出します。この呼び出しには PASSWORD_VERIFIER ChallengeName と、ChallengeResponses の必要なパラメータが使用されます。RespondToAuthChallenge の呼び出しが成功し、ユーザーのサインインが受け入れられると、Amazon Cognito によりトークンが発行されます。ユーザーの多要素認証 (MFA) を有効にした場合は、Amazon Cognito は、SMS_MFAChallengeName を返します。アプリは、RespondToAuthChallenge への別の呼び出しを通じて、必要なコードを提供できます。

カスタム認証フローとチャレンジ

アプリはカスタム認証フローを開始するために、InitiateAuthCUSTOM_AUTH として Authflow を呼び出すことができます。カスタム認証フローで、3 つの Lambda トリガーがチャレンジとレスポンスの検証を制御します。

  • DefineAuthChallenge Lambda トリガーは、以前のチャレンジとレスポンスのセッション配列を入力として使用します。そして、次のチャレンジ名と、ユーザーが認証済みで、トークンを付与できるかどうかを示すブール値を生成します。この Lambda トリガーは、チャレンジを通じてユーザーのパスを制御するステートマシンです。

  • CreateAuthChallenge Lambda トリガーは、チャレンジ名を入力として使用し、チャレンジとパラメータを生成してレスポンスを評価します。DefineAuthChallenge が次のチャレンジとして CUSTOM_CHALLENGE を返すと、認証フローは、CreateAuthChallenge を呼び出します。CreateAuthChallengeLambda トリガーは、チャレンジメタデータパラメータで次のタイプのチャレンジを渡します。

  • VerifyAuthChallengeResponse Lambda 関数は、レスポンスを評価し、レスポンスが有効であるかどうかを示すブール値を返します。

カスタム認証フローでは、SRP パスワードの検証や SMS を介した MFA などの、内部定義されたチャレンジを組み合わせて使用することもできます。CAPTCHA や秘密の質問などのカスタムチャレンジを使用できます。

カスタム認証フローにおける SRP パスワードの検証の使用

カスタム認証フローに SRP を含める場合には、最初に SRP を処理する必要があります。

  • カスタムフローで SRP パスワードの検証を開始する場合、アプリは InitiateAuthCUSTOM_AUTH として Authflow を呼び出します。AuthParameters マップで、アプリケーションからのリクエストは、SRP_A: (SRP A 値) および CHALLENGE_NAME: SRP_A を含んでいます。

  • CUSTOM_AUTH フローは、challengeName: SRP_A および challengeResult: true の初期セッションにより、DefineAuthChallenge の Lambda トリガーを呼び出します。Lambda 関数は、challengeName: PASSWORD_VERIFIERissueTokens: false、および failAuthentication: false により、応答します。

  • 次にアプリケーションは、(challengeName: PASSWORD_VERIFIER、そして challengeResponses マップ内の SRP に必要な他のパラメータを使用して) RespondToAuthChallenge を呼び出す必要があります。

  • Amazon Cognito がパスワードを検証すると、challengeName: PASSWORD_VERIFIERchallengeResult: true の 2 番目のセッションで、RespondToAuthChallenge により Lambda トリガーの DefineAuthChallenge が呼び出されます。その時点で DefineAuthChallenge Lambda トリガーは、challengeName: CUSTOM_CHALLENGE を使用して応答することでカスタムチャレンジを開始します。

  • MFA がユーザーに対して有効になっている場合、Amazon Cognito がパスワードを確認した後、ユーザーは MFA の設定またはサインインを要求されます。

注記

Amazon Cognito がホストするサインインウェブページは、カスタム認証チャレンジの Lambda トリガー をアクティブ化できません。

サンプルコードを含めた Lambda トリガーの詳細については、「Lambda トリガーを使用したユーザープールワークフローのカスタマイズ」を参照してください。

管理認証フロー

認証のベストプラクティスは、カスタム認証フローで説明されている API オペレーションを (SRP でのパスワード検証とともに) 使用することです。AWSSDK はこのアプローチを使用します。このアプローチは SRP の使用に役立ちます。ただし、SRP に関する計算を回避したい場合は、セキュアなバックエンドサーバーでは、代替の管理者 API オペレーションセットを利用できます。これらバックエンド管理の実装では、InitiateAuth の代わりに AdminInitiateAuth を使用します。同時に、RespondToAuthChallenge の代わりには AdminRespondToAuthChallenge を使用します。パスワードはプレーンテキストとして送信できるため、これらのオペレーションを使用するときに SRP 計算を実行する必要はありません。以下がその例です。

AdminInitiateAuth Request { "AuthFlow":"ADMIN_USER_PASSWORD_AUTH", "AuthParameters":{ "USERNAME":"<username>", "PASSWORD":"<password>" }, "ClientId":"<clientId>", "UserPoolId":"<userPoolId>" }

これらの管理認証オペレーションには、開発者の認証情報が必要であり、AWS Signature Version 4 (SigV4) の署名プロセスが使用されます。これらのオペレーションは、Lambda 関数にとって便利な、標準の AWS SDK (Node.js を含む) 内での使用が可能です。これらのオペレーションを使用し、同時にパスワードをプレーンテキストで受け入れるには、コンソールでそれらをアプリケーション向けに有効化する必要があります。または、ADMIN_USER_PASSWORD_AUTH または ExplicitAuthFlow への呼び出しで CreateUserPoolClientUpdateUserPoolClient パラメータに渡すことができます。InitiateAuth および RespondToAuthChallenge オペレーションでは、ADMIN_USER_PASSWORD_AUTH AuthFlow は受け入れられません。

AdminInitiateAuth からのレスポンス ChallengeParameters では、USER_ID_FOR_SRP 属性 (存在する場合) に、ユーザーのエイリアス (E メールアドレスや電話番号など) ではなく、実際のユーザー名が含まれています。AdminRespondToAuthChallenge への呼び出しの ChallengeResponses では、このユーザー名を USERNAME パラメータで渡す必要があります。

注記

バックエンド管理者実装は、管理者認証フローを使用しているため、フローはデバイス追跡をサポートしていません。デバイス追跡が有効にしている場合、管理者認証は成功しますが、アクセストークンの更新に関する呼び出しはいずれも失敗します。

ユーザー移行の認証フロー

ユーザー移行用 Lambda トリガーは、レガシーのユーザー管理システムからユーザープールにユーザーを移行する際に役立ちます。USER_PASSWORD_AUTH 認証フローを選択している場合には、移行中のユーザーがパスワードをリセットする必要はありません。このフローは、認証中に暗号化された SSL 接続を介してユーザーのパスワードをサービスに送信します。

すべてのユーザーの移行が完了したら、フローをよりセキュアな SRP フローに切り替えます。SRP フローは、ネットワーク経由でパスワードを送信しません。

Lambda トリガーの詳細については、「Lambda トリガーを使用したユーザープールワークフローのカスタマイズ」を参照してください。

Lambda トリガーを使用したユーザーの移行の詳細については、「ユーザー移行の Lambda トリガーを使用したユーザーのインポート」を参照してください。