ユーザー存在エラー応答の管理 - Amazon Cognito

ユーザー存在エラー応答の管理

Amazon Cognito は、ユーザープールから返されるエラーレスポンスのカスタマイズをサポートしています。カスタムエラーレスポンスは、ユーザーの作成と認証、パスワードリカバリ、および確認操作に利用できます。

ユーザープールアプリクライアントの PreventUserExistenceErrors 設定を使用して、ユーザーの存在に関連するエラーを有効または無効にします。Amazon Cognito ユーザープール API を使用して新しいアプリケーションクライアントを作成する場合、PreventUserExistenceErrors はデフォルトで LEGACY または無効になっています。Amazon Cognito コンソールでは、オプションのユーザー存在エラーの防止が、PreventUserExistenceErrorsENABLED とする設定としてデフォルトで選択されています。PreventUserExistenceErrors の設定を更新するには、次のいずれかを実行します。

  • UpdateUserPoolClient API リクエストで PreventUserExistenceErrors の値を ENABLEDLEGACY との間で変更します。

  • Amazon Cognito コンソールでアプリケーションクライアントを編集し、ユーザー存在エラーの防止の状態を、選択 (ENABLED) と選択解除 (LEGACY) との間で変更します。

このプロパティの値が LEGACY である場合、ユーザーがユーザープールに存在しないユーザー名でサインインしようとすると、アプリケーションクライアントは UserNotFoundException エラー応答を返します。

このプロパティの値が ENABLED である場合、アプリケーションクライアントは、ユーザープールにユーザーアカウントが存在しないことを UserNotFoundException エラーを用いて開示しません。PreventUserExistenceErrorsENABLED に設定した場合、存在しないユーザー名をリクエストすると、以下のようになります。

  • Amazon Cognito は API リクエストに対して非特定の情報で応答します。そうしない場合、その応答から有効なユーザーが存在することが開示される可能性があります。

  • Amazon Cognito は、パスワードを忘れた場合のリクエストに対して、さらに USER_SRP_AUTHCUSTOM_AUTH などの選択ベースの認証 (USER_AUTH) を除く認証フローによる認証リクエストに対して、一般的な認証失敗レスポンスを返します。エラーレスポンスは、ユーザー名またはパスワードが正しくないことを伝えます。

  • Amazon Cognito は、選択ベースの認証へのリクエストに対して、ユーザープールで許可されているチャレンジタイプからランダムに選択して応答します。ユーザープールは、パスキー、ワンタイムパスワード、またはパスワードチャレンジを返す場合があります。

  • Amazon Cognito のアカウント確認 API とパスワード復旧 API の動作は、シミュレートされた配信メディアにコードが送信されたことを示すレスポンスを返すか、InvalidParameterException エラーを返すかのいずれかです。

次の情報は、PreventUserExistenceErrorsENABLED に設定されている場合のユーザープールオペレーションの動作を詳しく示しています。

認証とユーザー作成のオペレーション

エラーレスポンスは、ユーザー名パスワード認証とセキュアリモートパスワード (SRP) 認証で設定できます。カスタム認証により、返すエラーをカスタマイズすることもできます。選択ベースの認証は、PreventUserExistenceErrors 設定の影響を受けません。

認証フローでのユーザー存在開示の詳細
選択ベースの認証

USER_AUTH 選択ベースの認証フローの場合、Amazon Cognito は、ユーザープール設定とユーザー属性に応じて、利用可能なプライマリ認証要素からチャレンジを返します。この認証フローでは、パスワード、セキュアリモートパスワード (SRP)、WebAuthn (パスキー)、SMS ワンタイムパスワード (OTP)、または E メール OTP チャレンジを返すことができます。PreventUserExistenceErrors がアクティブな場合、Amazon Cognito は、存在しないユーザーに対して 1 つ以上の利用可能な認証形式を完了するためのチャレンジを発行します。PreventUserExistenceErrors が非アクティブな場合、Amazon Cognito は UserNotFound 例外を返します。

ユーザー名およびパスワード認証

PreventUserExistenceErrors がアクティブな場合、ADMIN_USER_PASSWORD_AUTH 認証フロー、USER_PASSWORD_AUTH 認証フロー、および USER_AUTHPASSWORD フローは、メッセージ Incorrect username or password とともに NotAuthorizedException を返します。PreventUserExistenceErrors が非アクティブな場合、これらのフローは UserNotFoundException を返します。

セキュアリモートパスワード (SRP) ベースの認証

ベストプラクティスとして、E メールアドレス、電話番号、または優先ユーザー名のエイリアス属性がないユーザープールでは、PreventUserExistenceErrors を実装するのに USER_SRP_AUTH または USER_AUTHPASSWORD_SRP フローのみを使用します。エイリアス属性を持つユーザーは、SRP 認証フローでユーザー存在が抑制されない場合があります。ユーザー名パスワード認証フロー (ADMIN_USER_PASSWORD_AUTHUSER_PASSWORD_AUTH、および USER_AUTH PASSWORD チャレンジ) は、エイリアス属性からのユーザー存在を完全に抑制します。

アプリケーションクライアントに知られていないユーザー名を使用して誰かが SRP サインインを試みると、Amazon Cognito は、RFC 5054 で説明されているように、最初のステップでシミュレートされたレスポンスを返します。Amazon Cognito は、同じユーザー名とユーザープールの組み合わせに対して、同じ Salt と UUID 形式の内部ユーザー ID を返します。パスワードの証明を含む RespondToAuthChallenge API リクエストを送信すると、Amazon Cognito はユーザー名またはパスワードのいずれかが正しくない場合に一般的な NotAuthorizedException エラーを返します。SRP 認証の実装の詳細については、「永続的なパスワードと安全なペイロードによるサインイン」を参照してください。

注記

検証ベースのエイリアス属性を使用していて、変更不可能なユーザー名の形式が UUID でない場合は、ユーザー名とパスワードの認証で汎用応答をシミュレートできます。

カスタム認証チャレンジの Lambda トリガー

Amazon Cognito は、CUSTOM_AUTH 認証フローでサインインしようとしたユーザーのユーザー名が見つからない場合、カスタム認証チャレンジ Lambda トリガーを呼び出します。ユーザーが存在しない場合、入力イベントには UserNotFound という名前のブール型パラメータが true の値とともに含まれます。このパラメータは、カスタム認証アーキテクチャを構成する認証チャレンジの作成、定義、検証を行う Lambda 関数にユーザープールから送信するリクエストイベントに表示されます。このインジケータを Lambda 関数のロジックで確認したら、存在しないユーザーのカスタム認証チャレンジをシミュレートできます。

認証前の Lambda トリガー

Amazon Cognito は、サインインしようとしたユーザーのユーザー名が見つからない場合、認証前トリガーを呼び出します。ユーザーが存在しない場合、入力イベントには UserNotFound パラメータが true の値とともに含まれます。

ユーザーアカウントの作成に対する PreventUserExistenceErrors の影響について以下に説明します。

ユーザー作成フローでのユーザー存在開示の詳細
SignUp

SignUp オペレーションは、ユーザー名がすでに使用されている場合は必ず UsernameExistsException を返します。アプリケーションでユーザーをサインアップするときに Amazon Cognito が E メールアドレスと電話番号の UsernameExistsException エラーを返さないようにするには、検証ベースのエイリアス属性を使用してください。エイリアスの詳細については、「ログイン属性のカスタマイズ」を参照してください。

Amazon Cognito がSignUp API リクエストを使用してユーザープール内のユーザーを検出できないようにする方法の例については、「サインアップ時のメールアドレスと電話番号の UsernameExistsException エラーの防止」を参照してください。

インポート済みユーザー

PreventUserExistenceErrors が有効になっている場合は、インポートされたユーザーの認証中、PasswordResetRequiredException を返す代わりに、ユーザー名またはパスワードが正しくなかったことを示す NotAuthorizedException エラーが返されます。詳細については「インポートされたユーザーにパスワードをリセットするように要求」を参照してください。

ユーザー移行の Lambda トリガー

Lambda トリガーによって元のイベントコンテキストに空のレスポンスが設定された場合、Amazon Cognito は存在しないユーザーについてシミュレートされたレスポンスを返します。詳細については、「ユーザー移行の Lambda トリガーを使用したユーザーのインポート」を参照してください。

サインアップ時のメールアドレスと電話番号の UsernameExistsException エラーの防止

次の例は、ユーザープールでエイリアス属性を設定するときに、重複する E メールアドレスと電話番号が SignUp API リクエストに応答して UsernameExistsException エラーを生成しないようにする方法を示しています。E メールアドレスまたは電話番号をエイリアス属性として使用してユーザープールを作成しておく必要があります。詳細については、「ユーザープール属性」の「サインイン属性のカスタマイズ」セクションを参照してください。

  1. Jie は新しいユーザー名にサインアップし、E メールアドレス jie@example.com も提供します。Amazon Cognito がユーザーの E メールアドレスにコードを送信します。

    AWS CLI コマンドの例

    aws cognito-idp sign-up --client-id 1234567890abcdef0 --username jie --password PASSWORD --user-attributes Name="email",Value="jie@example.com"

    レスポンスの例

    { "UserConfirmed": false, "UserSub": "<subId>", "CodeDeliveryDetails": { "AttributeName": "email", "Destination": "j****@e****", "DeliveryMedium": "EMAIL" } }
  2. Jie は、E メールアドレスの所有権を確認するために送信されたコードを提供します。これで、ユーザーとしての登録は完了です。

    AWS CLI コマンドの例

    aws cognito-idp confirm-sign-up --client-id 1234567890abcdef0 --username=jie --confirmation-code xxxxxx
  3. Shirley は新しいユーザーアカウントを登録し、E メールアドレス jie@example.com を提供します。Amazon Cognito は UsernameExistsException エラーを返さず、確認コードを Jie の E メールアドレスに送信します。

    AWS CLI コマンドの例

    aws cognito-idp sign-up --client-id 1234567890abcdef0 --username shirley --password PASSWORD --user-attributes Name="email",Value="jie@example.com"

    レスポンスの例

    { "UserConfirmed": false, "UserSub": "<new subId>", "CodeDeliveryDetails": { "AttributeName": "email", "Destination": "j****@e****", "DeliveryMedium": "EMAIL" } }
  4. 別のシナリオでは、Shirley が jie@example.com の所有権を持っています。Shirley は Amazon Cognito が Jie の E メールアドレスに送信したコードを取得し、アカウントの確認を試みます。

    AWS CLI コマンドの例

    aws cognito-idp confirm-sign-up --client-id 1234567890abcdef0 --username=shirley --confirmation-code xxxxxx

    レスポンスの例

    An error occurred (AliasExistsException) when calling the ConfirmSignUp operation: An account with the email already exists.

jie@example.com が既存のユーザーに割り当てられているにもかかわらず、Amazon Cognito は Shirley の aws cognito-idp sign-up リクエストにエラーを返しません。Amazon Cognito がエラーレスポンスを返す前に、Shirley は E メールアドレスの所有権を証明する必要があります。エイリアス属性を持つユーザープールでは、この動作により、パブリック SignUp API を使用して、特定の E メールアドレスまたは電話番号を持つユーザーが存在するかどうかを確認できなくなります。

この動作は、次の例に示すように、Amazon Cognito が既存のユーザー名の SignUp リクエストに対して返すレスポンスとは異なります。Shirley はこのレスポンスから、そのユーザー名 jie を持つユーザーが既に存在することを知っていますが、そのユーザーに関連する E メールアドレスや電話番号については知りません。

CLI コマンドの例

aws cognito-idp sign-up --client-id 1example23456789 --username jie --password PASSWORD --user-attributes Name="email",Value="shirley@example.com"

レスポンスの例

An error occurred (UsernameExistsException) when calling the SignUp operation: User already exists

パスワードのリセットオペレーション

ユーザー存在エラーを防ぐと、Amazon Cognito は、ユーザーパスワードのリセット操作に対して以下の応答を返します。

ForgotPassword

ユーザーが見つからない、非アクティブ化されている、またはパスワードを回復するための検証済みの配信メカニズムがない場合、Amazon Cognito はそのユーザーについてシミュレート済みの配信ミディアムを用いた CodeDeliveryDetails を返します。シミュレートされた配信メディアは、入力ユーザー名形式とユーザープールの検証設定によって決まります。

ConfirmForgotPassword

Amazon Cognito は、存在しない、または無効になっているユーザーについて CodeMismatchException エラーを返します。ForgotPassword の使用時にコードが要求されない場合、Amazon Cognito は ExpiredCodeException エラーを返します。

確認オペレーション

ユーザー存在エラーを防ぐと、Amazon Cognito は、ユーザーの確認および検証の操作に対して以下の応答を返します。

ResendConfirmationCode

Amazon Cognito は、無効化されたユーザー、または存在しないユーザーについて CodeDeliveryDetails を返します。Amazon Cognito は、既存ユーザーの E メールまたは電話番号に確認コードを送信します。

ConfirmSignUp

ExpiredCodeExceptionコードの有効期限が切れている場合は、 が返されます。Amazon Cognito は、ユーザーが承認されていない場合に NotAuthorizedException を返します。コードがサーバーが期待するものと一致しない場合、Amazon Cognito は CodeMismatchException を返します。