管理用户存在错误响应 - Amazon Cognito
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

管理用户存在错误响应

Amazon Cognito 支持自定义由用户池返回的错误响应。自定义错误响应可用于用户创建和身份验证、密码恢复和确认操作。

使用用户池应用程序客户端的 PreventUserExistenceErrors 设置,以启用或禁用用户存在相关错误。当您使用 Amazon Cognito 用户池 API 创建新的应用程序时,默认情况下 PreventUserExistenceErrorsLEGACY 或禁用。在 Amazon Cognito 控制台中,默认选定防止用户已存在错误选项(PreventUserExistenceErrors 设置为 ENABLED)。要更新 PreventUserExistenceErrors 配置,请执行以下操作之一:

  • UpdateUserPoolClient API 请求中将 PreventUserExistenceErrors 的值更改为 ENABLEDLEGACY

  • 在 Amazon Cognito 控制台中编辑应用程序客户端,并将防止用户已存在错误的状态更改为选定(ENABLED)和已取消选择(LEGACY)。

当此属性的值为 LEGACY 时,当用户尝试使用您的用户池中不存在的用户名登录时,应用程序客户端会返回 UserNotFoundException 错误响应。

当此属性的值为 ENABLED 时,应用程序客户端不会通过 UserNotFoundException 错误来透露您的用户池中不存在某个用户账户。当 PreventUserExistenceErrors 配置为 ENABLED 时,如果您提交一个不存在的用户名请求,会产生以下效果:

  • Amazon Cognito 会使用非特定信息响应 API 请求,否则其响应可能会泄露存在有效的用户。

  • Amazon Cognito 会向密码重置请求以及使用 基于选择的身份验证USER_AUTH)之外的身份验证流程(例如 USER_SRP_AUTHCUSTOM_AUTH)的身份验证请求,返回通用的身份验证失败响应。错误响应告知您用户名或密码不正确。

  • 对于基于选择的身份验证请求,Amazon Cognito 会从用户池允许的质询类型中随机选择一种进行响应。您的用户池可能会返回通行密钥、一次性密码或密码质询。

  • Amazon Cognito 账户确认和密码恢复 API 的行为会在以下两种响应之间交替:一种是返回指示验证码已发送到模拟传送渠道的响应,另一种是返回 InvalidParameterException 错误。

以下信息详细说明了 PreventUserExistenceErrors 设置为 ENABLED 时用户池操作的行为。

身份验证和用户创建操作

您可以在用户名密码和安全远程密码(SRP)身份验证中配置错误响应。您还可以对使用自定义身份验证返回的错误进行自定义。基于选择的身份验证不受您的 PreventUserExistenceErrors 配置的影响。

身份验证流程中的用户存在性披露细节
基于选择的身份验证

USER_AUTH 基于选择的身份验证流程中,Amazon Cognito 会根据用户池配置和用户的属性,从可用的主身份验证因素中返回一个质询。该身份验证流程可能返回密码、安全远程密码(SRP)、WebAuthn(通行密钥)、短信一次性密码(OTP)或电子邮件 OTP 质询。当 PreventUserExistenceErrors 启用时,Amazon Cognito 会向不存在的用户发出质询,要求他们完成一种或多种可用的身份验证形式。当 PreventUserExistenceErrors 禁用时,Amazon Cognito 会返回 UserNotFound 异常。

用户名和密码身份验证

PreventUserExistenceErrors 启用时,身份验证流程 ADMIN_USER_PASSWORD_AUTHUSER_PASSWORD_AUTH 以及 USER_AUTHPASSWORD 流程会返回 NotAuthorizedException,附带 Incorrect username or password 消息。当 PreventUserExistenceErrors 禁用时,这些流会返回 UserNotFoundException

基于安全远程密码(SRP)的身份验证

作为最佳实践,应仅在没有配置电子邮件地址、电话号码或首选用户名别名属性的用户池中,对 USER_SRP_AUTHUSER_AUTH 中的 PASSWORD_SRP 流程实现 PreventUserExistenceErrors。在 SRP 身份验证流程中,具有别名属性的用户可能不会受到用户存在性隐藏的影响。用户名密码身份验证流程(ADMIN_USER_PASSWORD_AUTHUSER_PASSWORD_AUTHUSER_AUTH PASSWORD 质询)能够完全隐藏来自别名属性的用户存在性信息。

当有人使用应用程序客户端未知的用户名尝试 SRP 登录时,Amazon Cognito 会在第一步返回一个模拟响应,如 RFC 5054 所述。Amazon Cognito 始终针对相同的用户名和用户池组合返回相同的盐值以及 UUID 格式的内部用户 ID。当您发送带有密码证明的 RespondToAuthChallenge API 时,Amazon Cognito 在用户名或密码不正确时返回一个通用 NotAuthorizedException 错误。有关实施 SRP 身份验证的更多信息,请参阅使用永久密码和安全有效载荷登录

注意

如果您使用基于验证的别名属性,并且不可改变的用户名格式不是 UUID,则可以模拟使用用户名和密码身份验证的通用响应。

自定义身份验证质询 Lambda 触发器

当用户尝试使用 CUSTOM_AUTH 身份验证流程登录但其用户名未找到时,Amazon Cognito 会调用自定义身份验证质询 Lambda 触发器。输入事件中包含一个名为 UserNotFound 的布尔值参数,对于任何不存在的用户,该参数值为 true。此参数会出现在用户池发送给创建、定义和验证身份验证质询 Lambda 函数的请求事件中,这些函数构成自定义身份验证架构。在 Lambda 函数逻辑中检查该标识后,您可以为不存在的用户模拟自定义身份验证质询。

身份验证前 Lambda 触发器

当用户尝试登录但其用户名未找到时,Amazon Cognito 会调用身份验证前触发器。输入事件中包含一个 UserNotFound 参数,对于任何不存在的用户,该参数值为 true

以下列表描述了 PreventUserExistenceErrors 对用户账户创建的影响。

用户创建流程中的用户存在性披露细节
SignUp

当已使用用户名时,SignUp 操作始终返回 UsernameExistsException。如果在您的应用程序中注册用户时,您不希望 Amazon Cognito 为电子邮件地址和电话号码返回 UsernameExistsException 错误,请使用基于验证的别名属性。有关别名的更多信息,请参阅自定义登录属性

有关 Amazon Cognito 如何阻止使用 SignUp API 请求来发现用户池中用户的示例,请参阅 在注册时防止出现电子邮件地址和电话号码的 UsernameExistsException 错误

导入的用户

如果 PreventUserExistenceErrors 已启用,则在对导入的用户进行身份验证期间,将返回通用 NotAuthorizedException 错误,指示用户名或密码不正确,而不是返回 PasswordResetRequiredException。请参阅要求导入的用户重置密码了解更多信息。

迁移用户 Lambda 触发器

当 Lambda 触发器在原始事件上下文中设置了空响应时,Amazon Cognito 将为不存在的用户返回模拟响应。有关更多信息,请参阅利用用户迁移 Lambda 触发器导入用户

在注册时防止出现电子邮件地址和电话号码的 UsernameExistsException 错误

以下示例演示了在用户池中配置别名属性时,如何在对 SignUp API 请求的响应中,防止重复的电子邮件地址和电话号码生成 UsernameExistsException 错误。您必须在创建用户池时使用电子邮件地址或电话号码作为别名属性。有关更多信息,请参阅用户池属性自定义登录属性 部分。

  1. Jie 注册了一个新的用户名,还提供了电子邮件地址 jie@example.com。Amazon Cognito 将向其电子邮件地址发送一个代码。

    示例 Amazon 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 提供了发送过来的代码,确认其拥有该电子邮件地址。这样就完成了用户注册。

    示例 Amazon CLI 命令

    aws cognito-idp confirm-sign-up --client-id 1234567890abcdef0 --username=jie --confirmation-code xxxxxx
  3. Shirley 注册了一个新的用户账户并提供了电子邮件地址 jie@example.com。Amazon Cognito 不会返回 UsernameExistsException 错误,而是向 Jie 的电子邮件地址发送确认码。

    示例 Amazon 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 电子邮件地址的代码,并尝试确认该账户。

    示例 Amazon 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 必须证明对该电子邮件地址的所有权。在具有别名属性的用户池中,此行为会阻止使用公共 SignUp API 来检查是否存在具有给定电子邮件地址或电话号码的用户。

此行为与 Amazon Cognito 向使用现有用户名的 SignUp 请求返回的响应不同,如以下示例所示。尽管 Shirley 从此回复中得知已经存在具有用户名 jie 的用户,但他们并不知道与该用户关联的任何电子邮件地址或电话号码。

示例 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 会向现有用户的电子邮件或电话发送确认码。

ConfirmSignUp

ExpiredCodeException如果代码已过期,则将返回 。当用户未被授权时,Amazon Cognito 返回 NotAuthorizedException。1如果代码与服务器期望的代码不匹配,则 Amazon Cognito 返回 CodeMismatchException