認証フローの切り替え
AWSCognitoAuthPluginを使用すると、サインイン時に異なる認証フロー間で切り替えることができます。フローはamplify_outputs.jsonファイルで設定するか、signIn APIへのオプションとしてauthFlowTypeを渡すことで設定できます。
クライアント側の認証には、ランタイムで設定できる4つの異なるフローがあります。
-
USER_SRP_AUTH:USER_SRP_AUTHフローはSRPプロトコル(セキュアリモートパスワード)を使用し、パスワードはクライアントから離れることなく、サーバーには不明です。これは推奨されるフローであり、デフォルトで使用されます。 -
USER_PASSWORD_AUTH:USER_PASSWORD_AUTHフローはユーザー認証情報を暗号化されない状態でバックエンドに送信します。「Migration」トリガーを使用してユーザーをCognitoに移行し、ユーザーにパスワードのリセットを強制しない場合は、このトリガーで呼び出されるLambda関数が指定された認証情報を検証する必要があるため、このタイプを使用する必要があります。 -
CUSTOM_AUTH_WITH_SRP:CUSTOM_AUTH_WITH_SRPフローはSRP認証で開始してからカスタム認証に切り替えるために使用されます。初期認証にSRPを使用し、その後の認証試行にカスタム認証を使用したい場合に便利です。 -
CUSTOM_AUTH_WITHOUT_SRP:CUSTOM_AUTH_WITHOUT_SRPフローはSRPなしで認証フローを開始してから、異なる要件を満たすようにカスタマイズできるチャレンジと応答のサイクルのシリーズを使用するために使用されます。 -
USER_AUTH:USER_AUTHフローは、ユーザーが利用可能な認証方法のリストから選択できる、選択ベースの認証フローです。このフローは、ユーザーに認証方法を選択するオプションを提供したい場合に便利です。ユーザーに利用可能な選択肢は、EMAIL_OTP、SMS_OTP、WEB_AUTHN、PASSWORD、PASSWORD_SRPです。
AuthはAWSCognitoAuthSignInOptionsのauthFlowTypeをAuthFlowType.USER_PASSWORD_AUTH、AuthFlowType.CUSTOM_AUTH_WITHOUT_SRP、AuthFlowType.CUSTOM_AUTH_WITH_SRP、またはAuthFlowType.USER_AUTHとしてsignInを呼び出すことで、ランタイム時に異なるフローを使用するように設定できます。AWSCognitoAuthSignInOptionsでAuthFlowTypeを指定しない場合は、amplify_outputs.jsonで指定されたデフォルトフローが使用されます。
認証フローの詳細については、Amazon Cognitoデベロッパー向けドキュメントを参照してください。
USER_AUTH(選択ベースの認証)フロー
USER_AUTH認証フローのユースケースは、ユーザーに認証方法を選択するオプションを提供することです。ユーザーに利用可能な選択肢は、EMAIL_OTP、SMS_OTP、WEB_AUTHN、PASSWORD、PASSWORD_SRPです。
必要な第1要因がサインインフロー開始前にわかっている場合は、初期サインインコールに渡すことができます。
// PASSWORD_SRP / PASSWORD// 第1要因としてパスワードを使用してサインイン// 注:パスワードは同じステップで提供する必要がありますAuthSignInOptions options = AWSCognitoAuthSignInOptions.builder() .callingActivity(activity) .authFlowType(AuthFlowType.USER_AUTH) .preferredFirstFactor(AuthFactorType.PASSWORD_SRP) // または "PASSWORD" .build();Amplify.Auth.signIn( username, password, options, result -> Log.i("AuthQuickStart", "Next step for sign in is " + result.getNextStep()), error -> Log.e("AuthQuickStart", "Failed to confirm sign in", error));
// WEB_AUTHN / EMAIL_OTP / SMS_OTP// 第1要因としてパスワードレスチャレンジを使用してサインイン// このステップではユーザー入力は必要ありませんAuthSignInOptions options = AWSCognitoAuthSignInOptions.builder() .callingActivity(activity) .authFlowType(AuthFlowType.USER_AUTH) .preferredFirstFactor(AuthFactorType.WEB_AUTHN) // または "EMAIL_OTP" または "SMS_OTP" .build();Amplify.Auth.signIn( username, null, options, result -> Log.i("AuthQuickStart", "Next step for sign in is " + result.getNextStep()), error -> Log.e("AuthQuickStart", "Failed to confirm sign in", error));// PASSWORD_SRP / PASSWORD// 第1要因としてパスワードを使用してサインイン// 注:パスワードは同じステップで提供する必要がありますval options = AWSCognitoAuthSignInOptions.builder() .callingActivity(activity) .authFlowType(AuthFlowType.USER_AUTH) .preferredFirstFactor(AuthFactorType.PASSWORD_SRP) // または "PASSWORD" .build()Amplify.Auth.signIn( username, password, options, { result -> Log.i("AuthQuickStart", "Next step for sign in is ${result.nextStep}") }, { error -> Log.e("AuthQuickStart", "Failed to confirm sign in", error) })
// WEB_AUTHN / EMAIL_OTP / SMS_OTP// 第1要因としてパスワードレスチャレンジを使用してサインイン// このステップではユーザー入力は必要ありませんval options = AWSCognitoAuthSignInOptions.builder() .callingActivity(activity) .authFlowType(AuthFlowType.USER_AUTH) .preferredFirstFactor(AuthFactorType.WEB_AUTHN) // または "EMAIL_OTP" または "SMS_OTP" .build()Amplify.Auth.signIn( username, null, options, { result -> Log.i("AuthQuickStart", "Next step for sign in is ${result.nextStep}") }, { error -> Log.e("AuthQuickStart", "Failed to confirm sign in", error) })// PASSWORD_SRP / PASSWORD// 第1要因としてパスワードを使用してサインイン// 注:パスワードは同じステップで提供する必要がありますtry { val options = AWSCognitoAuthSignInOptions.builder() .callingActivity(activity) .authFlowType(AuthFlowType.USER_AUTH) .preferredFirstFactor(AuthFactorType.PASSWORD_SRP) // または "PASSWORD" .build() val result = Amplify.Auth.signIn( username = "hello@example.com", password = "password", options = options ) Log.i("AuthQuickstart", "Next step for sign in is ${result.nextStep}")} catch (error: AuthException) { Log.e("AuthQuickstart", "Sign in failed", error)}
// WEB_AUTHN / EMAIL_OTP / SMS_OTP// 第1要因としてパスワードレスチャレンジを使用してサインイン// このステップではユーザー入力は必要ありませんtry { val options = AWSCognitoAuthSignInOptions.builder() .callingActivity(activity) .authFlowType(AuthFlowType.USER_AUTH) .preferredFirstFactor(AuthFactorType.WEB_AUTHN) // または "EMAIL_OTP" または "SMS_OTP" .build() val result = Amplify.Auth.signIn( username = "hello@example.com", password = null, options = options ) Log.i("AuthQuickstart", "Next step for sign in is ${result.nextStep}")} catch (error: AuthException) { Log.e("AuthQuickstart", "Sign in failed", error)}// PASSWORD_SRP / PASSWORD// 第1要因としてパスワードを使用してサインイン// 注:パスワードは同じステップで提供する必要がありますAuthSignInOptions options = AWSCognitoAuthSignInOptions.builder() .callingActivity(activity) .authFlowType(AuthFlowType.USER_AUTH) .preferredFirstFactor(AuthFactorType.PASSWORD_SRP) // または "PASSWORD" .build();RxAmplify.Auth.signIn(username, password, options) .subscribe( result -> Log.i("AuthQuickstart", "Next step for sign in is " + result.getNextStep()), error -> Log.e("AuthQuickstart", "Failed to confirm sign in", error)) );
// WEB_AUTHN / EMAIL_OTP / SMS_OTP// 第1要因としてパスワードレスチャレンジを使用してサインイン// このステップではユーザー入力は必要ありませんAuthSignInOptions options = AWSCognitoAuthSignInOptions.builder() .callingActivity(activity) .authFlowType(AuthFlowType.USER_AUTH) .preferredFirstFactor(AuthFactorType.WEB_AUTHN) // または "EMAIL_OTP" または "SMS_OTP" .build();RxAmplify.Auth.signIn(username, null, options) .subscribe( result -> Log.i("AuthQuickstart", "Next step for sign in is " + result.getNextStep()), error -> Log.e("AuthQuickstart", "Failed to confirm sign in", error)) );推奨される第1要因が指定されていないか利用できない場合、複数の要因がユーザーに利用可能な場合、フローはCONTINUE_SIGN_IN_WITH_FIRST_FACTOR_SELECTIONのAuthNextSignInStep.signInStep値とAuthNextSignInStep.availableFactorsのリストを返すことで利用可能な第1要因の選択に続行します。
認証方法の選択はユーザーによって行われます。ユーザーは利用可能な要因から選択して、選択した要因で進めることができます。confirmSignIn APIを選択した要因で呼び出して、サインインプロセスを続行する必要があります。以下は、WEB_AUTHN要因を選択して進める場合の例です。
AuthConfirmSignInOptions options = AWSCognitoAuthConfirmSignInOptions.builder() .callingActivity(activity) .build();Amplify.Auth.confirmSignIn( AuthFactorType.WEB_AUTHN.getChallengeResponse(), options, result -> Log.i("AuthQuickStart", "Next step for sign in is " + result.getNextStep()), error -> Log.e("AuthQuickStart", "Failed to confirm sign in", error));val options = AWSCognitoAuthConfirmSignInOptions.builder() .callingActivity(activity) .build()Amplify.Auth.confirmSignIn( AuthFactorType.WEB_AUTHN.challengeResponse, options, { result -> Log.i("AuthQuickStart", "Next step for sign in is ${result.nextStep}") }, { error -> Log.e("AuthQuickStart", "Failed to confirm sign in", error) })try { val options = AWSCognitoAuthConfirmSignInOptions.builder() .callingActivity(activity) .build() val result = Amplify.Auth.confirmSignIn( challengeResponse = AuthFactorType.WEB_AUTHN.challengeResponse, options = options ) Log.i("AuthQuickstart", "Next step for sign in is ${result.nextStep}")} catch (error: AuthException) { Log.e("AuthQuickstart", "Sign in failed", error)}AuthConfirmSignInOptions options = AWSCognitoAuthConfirmSignInOptions.builder() .callingActivity(activity) .build();RxAmplify.Auth.confirmSignIn(AuthFactorType.WEB_AUTHN.getChallengeResponse(), options) .subscribe( result -> Log.i("AuthQuickstart", "Next step for sign in is " + result.getNextStep()), error -> Log.e("AuthQuickstart", "Failed to confirm sign in", error)) );USER_PASSWORD_AUTH フロー
USER_PASSWORD_AUTH認証フローのユースケースはAmazon Cognitoへのユーザー移行です。
ユーザー移行Lambda トリガーは、ユーザーをレガシーユーザー管理システムからユーザープールに移行するのに役立ちます。USER_PASSWORD_AUTH認証フローを選択する場合、ユーザーはユーザー移行中にパスワードをリセットする必要はありません。このフローは認証時にSSL接続経由でサービスにユーザーのパスワードを送信します。
すべてのユーザーを移行したら、より安全なSRPフローに切り替えてください。SRPフローはネットワーク経由でパスワードを送信しません。
AuthSignInOptions options = AWSCognitoAuthSignInOptions.builder() .authFlowType(AuthFlowType.USER_PASSWORD_AUTH) .build();Amplify.Auth.signIn( "hello@example.com", "password", options, result -> Log.i("AuthQuickStart", "Sign in succeeded with result " + result), error -> Log.e("AuthQuickStart", "Failed to sign in", error));val options = AWSCognitoAuthSignInOptions.builder() .authFlowType(AuthFlowType.USER_PASSWORD_AUTH) .build()Amplify.Auth.signIn( "hello@example.com", "password", options, { result -> Log.i("AuthQuickstart", "Next step for sign in is ${result.nextStep}") }, { error -> Log.e("AuthQuickstart", "Failed to sign in", error) })try { val options = AWSCognitoAuthSignInOptions.builder() .authFlowType(AuthFlowType.USER_PASSWORD_AUTH) .build() val result = Amplify.Auth.signIn( username = "hello@example.com", password = "password", options = options ) Log.i("AuthQuickstart", "Next step for sign in is ${result.nextStep}")} catch (error: AuthException) { Log.e("AuthQuickstart", "Sign in failed", error)}AuthSignInOptions options = AWSCognitoAuthSignInOptions.builder() .authFlowType(AuthFlowType.USER_PASSWORD_AUTH) .build();RxAmplify.Auth.signIn("hello@example.com", "password", options) .subscribe( result -> Log.i("AuthQuickstart", "Next step for sign in is " + result.getNextStep()), error -> Log.e("AuthQuickstart", error.toString()) );認証バックエンドのセットアップ
USER_PASSWORD_AUTH認証フローを使用するには、Cognitoアプリクライアントをこれを許可するように設定する必要があります。Amplify Gen 2ではデフォルトでSRP認証が有効になります。USER_PASSWORD_AUTHを有効にするには、backend.tsファイルを以下の変更で更新できます。
import { defineBackend } from '@aws-amplify/backend'import { auth } from './auth/resource'import { data } from './data/resource'
const backend = defineBackend({ auth, data,});
backend.auth.resources.cfnResources.cfnUserPoolClient.explicitAuthFlows = [ "ALLOW_USER_PASSWORD_AUTH", "ALLOW_USER_SRP_AUTH", "ALLOW_USER_AUTH", "ALLOW_REFRESH_TOKEN_AUTH"];Amazon Cognitoでユーザーを移行する
Amazon Cognitoは、既存のユーザーディレクトリからユーザーをCognitoにシームレスに移行するためのトリガーを提供します。これは、ユーザープールの「Migration」トリガーを設定して、ユーザープール内にまだ存在しないユーザーが認証するか、パスワードをリセットするたびにLambda関数を呼び出すことで実現されます。
簡潔に言えば、Lambda関数は既存のユーザーディレクトリに対してユーザー認証情報を検証し、成功時にユーザー属性と状態を含むレスポンスオブジェクトを返します。エラーが発生した場合はエラーメッセージが返されます。このフローをセットアップする方法に関するドキュメント、およびlambdaがリクエストレスポンスオブジェクトをどのように処理すべきかについてのより詳細な手順があります。
CUSTOM_AUTH フロー
Amazon Cognito User Poolsは、ユーザーのアイデンティティを検証するためにパスワードに加えてカスタムチャレンジタイプを有効にするために認証フローをカスタマイズできます。カスタム認証フローは、異なる要件を満たすようにカスタマイズできるチャレンジと応答のサイクルのシリーズです。これらのチャレンジタイプにはCAPTCHA、ダイナミックチャレンジ質問が含まれることがあります。
カスタム認証フローの課題を定義するために、Amazon Cognitoの3つのLambdaトリガーを実装する必要があります。
フローはAWSCognitoAuthSignInOptionsでAuthFlowType.CUSTOM_AUTH_WITH_SRPまたはAuthFlowType.CUSTOM_AUTH_WITHOUT_SRPで設定したsignInを呼び出すことで開始されます。
カスタム認証フローをアプリケーションと統合する方法についての詳細は、カスタム認証サインインの手順に従ってください。