

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 Amazon Cognito 用户池安全功能
<a name="managing-security"></a>

您可能想要保护应用程序，防止受到网络入侵、密码猜测、用户模拟以及恶意注册和登录的侵害。Amazon Cognito 用户池安全特征的配置是安全架构中的一个关键组件。您的应用程序的安全性是*客户责任 “云端安全”*，如[责任 AWS 共担模型](https://aws.amazon.com/compliance/shared-responsibility-model/)中所述。本章中的工具有助于使您的应用程序安全设计符合这些目标。

在配置用户池时，必须作出的一项重要决定是，是否允许公开注册和登录。某些用户池选项（例如机密客户端、以管理员身份创建用户和确认，以及没有域的用户池）受到互联网攻击影响的程度较小。而一个常见的使用场景是公共客户端，它们接受互联网上任何人的注册并将所有操作直接发送到您的用户池。在任何配置中（尤其是在这些公共配置中），我们建议在规划和部署用户池时要考虑安全特征。当不受欢迎的来源创建新的活跃用户或试图利用现有用户时，安全性不足也会影响您的 AWS 账单。

MFA 和威胁防护适用于[本地用户](cognito-terms.md#terms-localuser)。第三方 IdPs 应对[联合用户](cognito-terms.md#terms-federateduser)的安全状况负责。用户池安全特征

**多重身份验证 (MFA)**  
请求一个由用户池通过电子邮件（使用基础版或增值版功能计划）或短信或身份验证器应用程序发送的验证码，用以确认用户池登录。

**威胁防护**  
监控登录以了解风险指标，并应用 MFA 或阻止登录。向访问令牌添加自定义声明和范围。通过电子邮件发送 MFA 代码。

**AWS WAF 网页 ACLs**  
检查[用户池端点和身份验证 API](authentication-flows-public-server-side.md#user-pools-API-operations) 的传入流量，以了解网络层和应用程序层是否存在不想要的活动。

**区分大小写**  
防止创建除了字符大小写有所不同之外，其电子邮件地址或首选用户名与另一个用户完全相同的用户。

**删除保护**  
防止自动化系统意外删除您的用户池。需要在 AWS 管理控制台中进一步确认删除用户池。

**用户存在错误**  
防止披露用户池中现有的用户名和别名。无论用户名是否有效，在身份验证失败时都返回一个通用错误。

**Topics**
+ [向用户池添加 MFA](user-pool-settings-mfa.md)
+ [具备威胁防护的高级安全功能](cognito-user-pool-settings-threat-protection.md)
+ [将 AWS WAF Web ACL 与用户池关联](user-pool-waf.md)
+ [用户池区分大小写](user-pool-case-sensitivity.md)
+ [用户池删除保护](user-pool-settings-deletion-protection.md)
+ [管理用户存在错误响应](cognito-user-pool-managing-errors.md)

# 向用户池添加 MFA
<a name="user-pool-settings-mfa"></a>

MFA 将*您具有的某种* 身份验证因素添加到*您已知的* 初始因素（通常是用户名和密码）中。对于使用密码作为主要身份验证因素的用户，您可以选择将短信文本消息、电子邮件消息或基于时间的一次性密码（TOTP）作为他们登录的额外安全因素。

多重身份验证（MFA）可提高应用程序中[本地用户](cognito-terms.md#terms-localuser)的安全性。对于[联合用户](cognito-terms.md#terms-federateduser)，Amazon Cognito 会将所有身份验证过程委托给 IdP，并且不会为他们提供额外的身份验证因素。

**注意**  
即使您的用户池需要 MFA，新用户首次登录您的应用程序时，Amazon Cognito 也会发放 OAuth 2.0 令牌。您的用户首次登录时的第二个身份验证因素是他们对 Amazon Cognito 发送给他们的验证消息的确认。如果您的用户池要求使用 MFA，Amazon Cognito 会提示您的用户注册一个额外的登录因素，以便在第一次之后的每次登录尝试期间使用。

借助自适应身份验证，可以将用户池配置为响应增加的风险级别需要额外的身份验证因素。要向用户池添加自适应身份验证，请参阅 [具备威胁防护的高级安全功能](cognito-user-pool-settings-threat-protection.md)。

将用户池的 MFA 设置为 `required` 时，所有用户都必须完成 MFA 才能登录。要登录，每个用户至少设置一个 MFA 安全因素。当需要进行 MFA 时，您必须在用户引导中包含 MFA 设置，以便您的用户池允许他们登录。

当您将 MFA 设置为必需时，托管登录会提示用户设置 MFA。当您在用户池中将 MFA 设置为可选时，托管登录不会提示用户。要使用可选的 MFA，您必须在应用程序中构建一个界面，以提示用户选择他们需要设置 MFA，然后引导他们完成 API 输入以验证他们的额外登录因素。

**Topics**
+ [有关用户池 MFA 的需知信息](#user-pool-settings-mfa-prerequisites)
+ [用户 MFA 首选项](#user-pool-settings-mfa-preferences)
+ [用户运行时的 MFA 逻辑详情](#user-pool-settings-mfa-user-outcomes)
+ [为用户池配置多重身份验证](#user-pool-configuring-mfa)
+ [短信和电子邮件消息 MFA](user-pool-settings-mfa-sms-email-message.md)
+ [TOTP 软件令牌 MFA](user-pool-settings-mfa-totp.md)

## 有关用户池 MFA 的需知信息
<a name="user-pool-settings-mfa-prerequisites"></a>

在设置 MFA 之前，请考虑以下情况：
+ *用户可以拥有 MFA，也可以使用无密码因素登录，但有一个例外：当您在用户池中设置为时，带有用户验证功能的密钥可以满足 MFA 要求。* `FactorConfiguration` `MULTI_FACTOR_WITH_USER_VERIFICATION` `WebAuthnConfiguration`
  + 在支持[一次性](amazon-cognito-user-pools-authentication-flow-methods.md#amazon-cognito-user-pools-authentication-flow-methods-passwordless)密码的用户池中，您不能将 MFA 设置为必填项。
  + 当您的用户池中需要 MFA `AllowedFirstAuthFactors` 时，您无法添加`EMAIL_OTP`或`SMS_OTP`。您可以添加`WEB_AUTHN`何时设置`FactorConfiguration`为`MULTI_FACTOR_WITH_USER_VERIFICATION`。
  + 当用户池要求启用 MFA 时，所有应用程序客户端中[基于选择的登录](authentication-flows-selection-sdk.md#authentication-flows-selection-choice)仅提供 `PASSWORD` 和 `PASSWORD_SRP` 两种因素。有关用户名密码流程的更多信息，请参阅本指南**身份验证**一章中的[使用永久密码登录](amazon-cognito-user-pools-authentication-flow-methods.md#amazon-cognito-user-pools-authentication-flow-methods-password)和[使用永久密码和安全有效载荷登录](amazon-cognito-user-pools-authentication-flow-methods.md#amazon-cognito-user-pools-authentication-flow-methods-srp)。
  + 在 MFA 为可选的用户池中，已配置 MFA 因素的用户在使用基于选择的登录时，只能通过用户名密码的身份验证流程进行登录。这些用户有资格使用所有[基于客户端的登录](authentication-flows-selection-sdk.md#authentication-flows-selection-client)流程。

  下表描述了用户池的 MFA 设置及用户对 MFA 因素的配置对用户使用无密码因素登录的能力的影响。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/user-pool-settings-mfa.html)
+ 用户首选 MFA 方法会影响他们可用于恢复密码的方法。首选 MFA 方式为电子邮件的用户无法通过电子邮件接收密码重置代码。首选 MFA 方式为短信的用户无法通过短信接收密码重置代码。

  当用户不符合条件，无法使用首选密码重置方法时，您的[密码恢复](managing-users-passwords.md#user-pool-password-reset-and-recovery)设置必须提供替代选项。例如，您的恢复机制可能将电子邮件列为第一优先选项，而电子邮件 MFA 可能是您的用户池中的一个选项。在这种情况下，添加短信消息账户恢复作为第二个选项，或者使用管理 API 操作为这些用户重置密码。

  对于没有有效恢复方式的用户发起的密码重置请求，Amazon Cognito 会返回 `InvalidParameterException` 错误响应。

  的示例请求正文[UpdateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPool.html#API_UpdateUserPool_Examples)说明了当电子邮件密码重置不可用时，用户可以通过短信回退到恢复状态。`AccountRecoverySetting`
+ 用户无法在同一电子邮件地址或电话号码上接收 MFA 验证码和密码重置验证码。如果他们使用电子邮件中的一次性密码 (OTPs) 进行 MFA，则必须使用 SMS 消息进行账户恢复。如果他们使用来 OTPs 自 SMS 消息的 MFA，则必须使用电子邮件进行账户恢复。在具有 MFA 的用户池中，如果用户有电子邮件地址的属性但没有电话号码，或者有电话号码但没有电子邮件地址，则他们可能无法完成自助密码恢复。

  要防止用户无法在使用此配置的用户池中重置密码的情况，请设置 `email` 和 `phone_number` [属性（按需设置）](user-pool-settings-attributes.md)。或者，您可以设置相关流程，在用户注册时或管理员创建用户配置文件时，始终收集并设置这些属性。当用户同时具备这两个属性时，Amazon Cognito 会自动将密码重置验证码发送到*不是*用户 MFA 因素的目的地。
+ 当您在用户池中激活 MFA 并选择**短信**或**电子邮件消息**作为第二安全因素时，可以向尚未在 Amazon Cognito 中验证的电话号码或电子邮件属性发送消息。用户完成 MFA 后，Amazon Cognito 会将其 `phone_number_verified` 或 `email_verified` 属性设置为 `true`。
+ 在五次尝试提交 MFA 代码均未成功后，Amazon Cognito 会开始如[失败登录尝试的锁定行为](authentication.md#authentication-flow-lockout-behavior)中所描述的指数超时锁定过程。
+ 如果您的账户位于包含您的用户池的亚马逊简单通知服务 (Amazon SNS) Simple Notification Service 资源的短信沙箱中，则必须先验证亚马逊 SNS 中的电话号码，然后才能发送短信。 AWS 区域 有关更多信息，请参阅 [Amazon Cognito 用户池的短信设置](user-pool-sms-settings.md)。
+ 为了更改用户的 MFA 状态以响应威胁防护功能检测到的事件，请激活 MFA 并在 Amazon Cognito 用户池控制台中将其设置为可选。有关更多信息，请参阅 [具备威胁防护的高级安全功能](cognito-user-pool-settings-threat-protection.md)。
+ 电子邮件和短信消息要求您的用户分别具有电子邮件地址和电话号码属性。您可以在用户池中将 `email` 或 `phone_number` 设置为必需的属性。在这种情况下，除非用户提供电话号码，否则他们无法完成注册。如果您未将这些属性设置为必需，但想要进行电子邮件或短信消息 MFA，则可以在用户注册时提示他们输入电子邮件地址或电话号码。妥善的做法是将用户池配置为自动向用户发送消息来[验证这些属性](signing-up-users-in-your-app.md)。

  如果用户通过短信或电子邮件成功接收了临时验证码，并在 [VerifyUserAttribute](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_VerifyUserAttribute.html)API 请求中返回了该验证码，则 Amazon Cognito 会将电话号码或电子邮件地址视为已验证。或者，您的团队可以设置电话号码，并使用执行 [AdminUpdateUserAttributes](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminUpdateUserAttributes.html)API 请求的管理应用程序将其标记为已验证。
+ 如果您已将 MFA 设置为必需且激活了多个身份验证因素，则 Amazon Cognito 会提示新用户选择他们想要使用的 MFA 因素。用户必须有电话号码才能设置短信消息 MFA，必须有电子邮件地址才能设置电子邮件消息 MFA。如果用户没有为任何基于消息的可用 MFA 定义属性，则 Amazon Cognito 会提示他们设置 TOTP MFA。选择 MFA 因子 (`SELECT_MFA_TYPE`) 和设置所选因子 (`MFA_SETUP`) 的提示是对[InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)和 [AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html)API 操作的质询响应。

## 用户 MFA 首选项
<a name="user-pool-settings-mfa-preferences"></a>

用户可以设置多个 MFA 因素。只能激活一个因素。您可以在用户池设置中或从用户提示为用户选择有效的 MFA 首选项。当用户池设置和他们自己的用户级设置满足以下条件时，用户池会提示用户输入 MFA 验证码：

1. 您可以在用户池中将 MFA 设置为可选或必需。

1. 用户具有有效的 `email` 或 `phone_number` 属性，或者已为 TOTP 设置身份验证器应用程序。

1. 至少有一个 MFA 因素处于活动状态。

1. 一个 MFA 因素设置为首选。

### 禁止在登录和 MFA 中使用相同的系数
<a name="user-pool-settings-mfa-preferences-same-factor"></a>

可以配置您的用户池，使一个登录因子成为部分或所有用户唯一可用的登录和 MFA 选项。当您的主要登录用例是电子邮件或短信一次性密码 () 时，可能会出现此结果。OTPs在以下条件下，用户的首选 MFA 可能与其登录的因素类型相同：
+ 用户池中需要 MFA。
+ 用户池中提供电子邮件和短信 OTP 登录和 *MF* A 选项。
+ 用户使用电子邮件或短信 OTP 登录。
+ 它们有电子邮件地址属性但没有电话号码属性，或者有电话号码属性但没有电子邮件地址属性。

在这种情况下，用户可以使用电子邮件 OTP 登录，并使用电子邮件 OTP 完成 MFA。此选项取消了 MFA 的基本功能。使用一次性密码登录的用户必须能够使用与 MFA 不同的交付方式进行登录。当用户同时使用短信和电子邮件选项时，Amazon Cognito 会自动分配不同的因子。例如，当用户使用电子邮件 OTP 登录时，他们的首选 MFA 是短信 OTP。

当您的用户池支持登录和 MFA 的 OTP 身份验证时，请执行以下步骤来解决同因子身份验证问题。

1. 启用电子邮件和短信 OTP 作为登录因子。

1. 启用电子邮件和短信 OTP 作为 MFA 因子。

1. 收集

### 用户池设置及其对 MFA 选项的影响
<a name="user-pool-settings-mfa-preferences-things-to-know"></a>

用户池的配置会影响用户可以选择的 MFA 方法。以下是一些会影响用户设置 MFA 能力的用户池设置。
+ 在 Amazon Cognito 控制台**登录**菜单中的**多重身份验证**配置中，您可以将 MFA 设置为可选或必需，也可以将其关闭。与此设置的 API 等效项是`CreateUserPool``UpdateUserPool`、和的[MfaConfiguration](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html#CognitoUserPools-CreateUserPool-request-MfaConfiguration)参数`SetUserPoolMfaConfig`。

  此外，在**多重身份验证**配置中，**MFA 方法**设置决定了用户可以设置的 MFA 因素。与该设置相当的 API 就是[SetUserPoolMfaConfig](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_SetUserPoolMfaConfig.html)操作。
+ 在**用户账户恢复**下的**登录**菜单中，您可以配置用户池向忘记密码的用户发送消息的方式。用户的 MFA 方法不能与用户池用于发送“忘记密码”验证码的 MFA 传送方式相同。忘记密码传送方法的 API 参数是和的[AccountRecoverySetting](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html#CognitoUserPools-CreateUserPool-request-AccountRecoverySetting)参数。`CreateUserPool` `UpdateUserPool`

  例如，当恢复选项为**仅使用电子邮件**时，用户无法设置电子邮件 MFA。这是因为在同一个用户池中，您无法既启用电子邮件 MFA 又将恢复选项设置为**仅使用电子邮件**。当您将此选项设置为**如果电子邮件可用，则使用电子邮件发送，否则使用短信**时，电子邮件是优先恢复选项，但是当用户不符合通过电子邮件进行恢复的条件时，您的用户池可以回退到短信形式。在这种情况下，用户可以将电子邮件 MFA 设置为首选，并且只在尝试重置密码时才接收短信。
+ 如果您只将一种 MFA 方法设置为可用，则无需管理用户 MFA 首选项。
+ 激活的短信配置会自动使短信成为用户池中的可用 MFA 方法。

  用户池中包含您自己的 Amazon SES 资源的有效[电子邮件配置](user-pool-email.md)以及基础版或增值版功能计划，可自动使电子邮件消息成为用户池中的可用 MFA 方法。
+ 在用户池中将 MFA 设置为必需时，用户无法启用或禁用任何 MFA 方法。您只能设置首选方法。
+ 当您在用户池中将 MFA 设置为可选时，托管登录不会提示用户设置 MFA，而是在用户拥有首选 MFA 方法时，提示用户输入 MFA 验证码。
+ 当您激活[威胁防护](cognito-user-pool-settings-threat-protection.md)并在全功能模式下配置自适应身份验证响应时，在您的用户池中 MFA 必须是可选的。自适应身份验证的其中一个响应选项是要求其登录尝试被评估为包含一定风险级别的用户进行 MFA。

  控制台的**注册**菜单中的**必填属性**设置决定了用户是否必须提供电子邮件地址或电话号码才能注册您的应用程序。当用户具有相应属性时，电子邮件和短信将成为符合条件的 MFA 因素。`CreateUserPool` 的 [Schema](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html#CognitoUserPools-CreateUserPool-request-Schema) 参数根据需要设置属性。
+ 当您在用户池中将 MFA 设置为必需且用户使用托管登录进行登录时，Amazon Cognito 会提示他们从用户池的可用方法中选择 MFA 方法。托管登录负责收集电子邮件地址或电话号码并设置 TOTP。下图展示了 Amazon Cognito 向用户提供的选项背后的逻辑。

### 为用户配置 MFA 首选项
<a name="user-pool-settings-mfa-preferences-configure"></a>

您可以在具有访问令牌授权的自助服务模式中为用户配置 MFA 首选项，或者在具有管理 API 操作的管理员管理模式中为用户配置 MFA 首选项。这些操作启用或禁用 MFA 方法，并将多种方法之一设置为首选选项。在用户设置 MFA 首选项后，Amazon Cognito 会在登录时提示他们提供来自他们首选 MFA 方法的验证码。未设置首选项的用户会收到在 `SELECT_MFA_TYPE` 质询中选择首选方法的提示。
+ 在用户自助服务模式或公共应用程序中 [SetUserMfaPreference](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_SetUserMFAPreference.html)，使用登录用户的访问令牌进行授权，设置 MFA 配置。
+ 在管理员管理的应用程序或机密应用程序中，使用管理 AWS 凭证进行授权 [AdminSetUserPreference](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminSetUserMFAPreference.html)，设置 MFA 配置。

您也可以从 Amazon Cognito 控制台的**用户**菜单中设置用户 MFA 首选项。有关 Amazon Cognito 用户池 API 中的公共和机密身份验证模式的更多信息，请参阅[了解 API、OIDC 和托管登录页面身份验证](authentication-flows-public-server-side.md#user-pools-API-operations)。

## 用户运行时的 MFA 逻辑详情
<a name="user-pool-settings-mfa-user-outcomes"></a>

为确定用户登录时要采取的步骤，您的用户池会评估用户 MFA 首选项、[用户属性](user-pool-settings-attributes.md)、[用户池 MFA 设置](#user-pool-configuring-mfa)、[威胁防护](cognito-user-pool-settings-adaptive-authentication.md)操作和[自助账户恢复](managing-users-passwords.md#user-pool-password-reset-and-recovery)设置。然后，它会让用户登录，提示他们选择 MFA 方法、设置 MFA 方法或进行 MFA 验证。要设置 MFA 方法，用户必须提供[电子邮件地址或电话号码](user-pool-settings-mfa-sms-email-message.md)或[注册 TOTP 身份验证器](user-pool-settings-mfa-totp.md#totp-mfa-set-up-api)。他们还可以设置 MFA 选项并提前[注册首选项](#user-pool-settings-mfa-preferences-configure)。下图列出了用户池配置对初始注册后立即登录尝试的详细影响。

此图所示的逻辑适用于基于 SDK 的应用程序和[托管登录](cognito-user-pools-managed-login.md)登录流程，但在托管登录中较不明显。当您排查 MFA 的问题时，应从用户遇到的结果出发，反向追溯到用户配置文件以及影响该结果的用户池配置。

![\[便于最终用户选择 MFA 方法的 Amazon Cognito 用户池决策过程示意图。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/cup-mfa-decision-tree.png)


以下清单对应于决策逻辑图中的编号，并详细描述了每个步骤。![\[checkmark\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/checkmark.png) 表示身份验证成功且流程已结束。![\[error\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/error.png) 表示身份验证失败。

1. 用户在登录界面输入其用户名，或用户名和密码。如果提供的凭证无效，其登录请求将被拒绝。

1. 如果用户成功通过用户名密码身份验证，则需判断 MFA 是必需、可选还是关闭。如果关闭，则使用正确的用户名和密码即可成功进行身份验证。![\[Green circular icon with a checkmark symbol inside.\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/checkmark.png)

   1. 如果 MFA 为可选，需判断用户之前是否已设置 TOTP 身份验证器。如果已设置 TOTP，则提示用户进行 TOTP MFA。如果用户成功响应该 MFA 质询，即可成功登录。![\[Green circular icon with a checkmark symbol inside.\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/checkmark.png)

   1. 判断威胁防护的自适应身份验证功能是否已要求该用户设置 MFA。如果未分配 MFA，则用户可成功登录。![\[Green circular icon with a checkmark symbol inside.\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/checkmark.png)

1. 如果 MFA 为必需，或自适应身份验证已为用户分配 MFA，则需判断该用户是否已启用并设定首选的 MFA 因素。如果有，则使用该因素提示用户进行 MFA 验证。如果用户成功响应该 MFA 质询，即可成功登录。![\[Green circular icon with a checkmark symbol inside.\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/checkmark.png)

1. 如果用户尚未设置 MFA 首选项，则需判断该用户是否已注册 TOTP 身份验证器。

   1. 如果用户已注册 TOTP 身份验证器，则需判断该用户池中是否启用了 TOTP MFA（即使用户之前已设置身份验证器，此后 TOTP MFA 仍可能被禁用）。

   1. 判断用户池中电子邮件消息或短信形式的 MFA 是否也可用。

   1.  如果电子邮件和短信 MFA 均不可用，则提示用户进行 TOTP MFA 验证。如果用户成功响应该 MFA 质询，即可成功登录。![\[Green circular icon with a checkmark symbol inside.\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/checkmark.png)

   1. 如果电子邮件或短信 MFA 可用，则需判断用户是否具有相应的 `email` 或 `phone_number` 属性。如果已设置，则任何未被用作自助账户恢复的主要方式且已启用用于 MFA 的属性，均可供用户使用。

   1. 向用户发起一个 `SELECT_MFA_TYPE` 质询，其中 `MFAS_CAN_SELECT` 选项包含 TOTP 以及可用的短信或电子邮件 MFA 因素。

   1.  根据用户在 `SELECT_MFA_TYPE` 质询中选择的因素，提示用户完成该因素的验证。如果用户成功响应该 MFA 质询，即可成功登录。![\[Green circular icon with a checkmark symbol inside.\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/checkmark.png)

1. 如果用户尚未注册 TOTP 身份验证器，或者已注册但 TOTP MFA 当前已禁用，则需判断该用户是否设置了 `email` 或 `phone_number` 属性。

1.  如果用户仅有一个电子邮件地址或仅有一个电话号码，则需判断该属性是否同时也是用户池用于发送密码重置账户恢复消息的方式。如果是，则在 MFA 为必需的情况下，用户无法完成登录，Amazon Cognito 将返回错误。要使该用户成功登录，必须为其添加一个非恢复用途的属性，或为其注册一个 TOTP 身份验证器。![\[alt text not found\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/error.png)

   1. 如果用户拥有可用的、非恢复用途的电子邮件地址或电话号码，则需判断对应的电子邮件或短信 MFA 因素是否已启用。

   1. 如果用户拥有非恢复用途的电子邮件地址属性，且电子邮件 MFA 已启用，则可向其发起 `EMAIL_OTP` 质询。如果用户成功响应该 MFA 质询，即可成功登录。![\[Green circular icon with a checkmark symbol inside.\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/checkmark.png)

   1. 如果用户拥有非恢复用途的电话号码属性，且短信 MFA 已启用，则可向其发起 `SMS_MFA` 质询。如果用户成功响应该 MFA 质询，即可成功登录。![\[Green circular icon with a checkmark symbol inside.\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/checkmark.png)

   1. 如果用户没有可用于已启用电子邮件或短信 MFA 因素的属性，则需判断 TOTP MFA 是否已启用。如果 TOTP MFA 已禁用，则在 MFA 为必需的情况下，用户无法完成登录，Amazon Cognito 将返回错误。要使该用户成功登录，必须为其添加一个非恢复用途的属性，或为其注册一个 TOTP 身份验证器。![\[alt text not found\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/error.png)
**注意**  
如果用户已注册 TOTP 身份验证器但 TOTP MFA 已禁用，则此步骤此前已被判定为**否**。

   1. 如果 TOTP MFA 已启用，则向用户发起一个 `MFA_SETUP` 质询，并在 `MFAS_CAN_SETUP` 选项中包含 `SOFTWARE_TOKEN_MFA`。要完成此质询，您必须单独为用户注册一个 TOTP 身份验证器，然后使用 `"ChallengeName": "MFA_SETUP", "ChallengeResponses": {"USERNAME": "[username]", "SESSION": "[Session ID from VerifySoftwareToken]}"` 进行回应。

   1. 用户使用[VerifySoftwareToken](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_VerifySoftwareToken.html)请求中的会话令牌回应`MFA_SETUP`质询后，提示他们提出`SOFTWARE_TOKEN_MFA`质疑。如果用户成功响应该 MFA 质询，即可成功登录。![\[Green circular icon with a checkmark symbol inside.\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/checkmark.png)

1. 如果用户同时拥有电子邮件地址和电话号码，则需判断其中哪一个属性（如果有的话）是密码重置账户恢复消息的主要发送方式。

   1. 如果自助账户恢复功能已禁用，则这两个属性均可用于 MFA。需判断电子邮件 MFA、短信 MFA 或两者是否已启用。

   1. 如果这两个属性均已启用为 MFA 因素，则向用户发起一个 `SELECT_MFA_TYPE` 质询，其中 `MFAS_CAN_SELECT` 选项为 `SMS_MFA` 和 `EMAIL_OTP`。

   1. 根据用户在 `SELECT_MFA_TYPE` 质询中选择的因素，提示他们完成该因素的验证。如果用户成功响应该 MFA 质询，即可成功登录。![\[Green circular icon with a checkmark symbol inside.\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/checkmark.png)

   1. 如果仅有一个属性符合 MFA 因素的条件，则向用户发起对应另一个因素的质询。如果用户成功响应该 MFA 质询，即可成功登录。![\[Green circular icon with a checkmark symbol inside.\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/checkmark.png)

      如果存在以下情形，可能会发生这种结果。

      1. 当用户同时拥有 `email` 和 `phone_number` 属性，短信和电子邮件 MFA 均已启用，且账户恢复的主要方式已设定为通过电子邮件或短信时。

      1. 当用户同时拥有 `email` 和 `phone_number` 属性，仅短信 MFA 或电子邮件 MFA 之一已启用，且自助账户恢复已禁用时。

1. 如果用户尚未注册 TOTP 身份验证器，且既无 `email` 也无 `phone_number` 属性，则向其发起一个 `MFA_SETUP` 质询。`MFAS_CAN_SETUP` 列表中包含用户池中所有已启用且不是账户恢复主要选项的 MFA 因素。用户可通过 `ChallengeResponses` 响应此质询，以设置电子邮件或 TOTP MFA。要设置短信 MFA，必须先单独为用户添加电话号码属性，然后重新开始身份验证流程。

   对于 TOTP MFA，使用 `"ChallengeName": "MFA_SETUP", "ChallengeResponses": {"USERNAME": "[username]", "SESSION": "[Session ID from VerifySoftwareToken]"}` 进行响应。

   对于电子邮件 MFA，使用 `"ChallengeName": "MFA_SETUP", "ChallengeResponses": {"USERNAME": "[username]", "email": "[user's email address]"}` 进行响应。

   1. 根据用户在 `SELECT_MFA_TYPE` 质询中选择的因素，提示他们完成该因素的验证。如果用户成功响应该 MFA 质询，即可成功登录。![\[Green circular icon with a checkmark symbol inside.\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/checkmark.png)

## 为用户池配置多重身份验证
<a name="user-pool-configuring-mfa"></a>

您可以在 Amazon Cognito 控制台中配置 MFA，也可以使用 API 操作和 SD [SetUserPoolMfaConfig](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_SetUserPoolMfaConfig.html)K 方法进行配置。

**在 Amazon Cognito 控制台中配置 MFA**

1. 登录 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)。

1. 选择**用户池**。

1. 从列表中选择一个现有用户池，或[创建一个用户池](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-as-user-directory.html)。

1. 选择**登录**菜单。找到**多重身份验证**，然后选择**编辑**。

1. 选择您希望用于用户池的**MFA 强制执行**方法。  
![\[一张来自 Amazon Cognito 控制台的屏幕截图，显示了 MFA 选项。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/cup-mfa.png)

   1. **需要 MFA**。用户池中的所有用户必须使用额外的短信验证码、电子邮件验证码或基于时间的一次性密码（TOTP）验证码作为额外的身份验证因素进行登录。

   1. **可选 MFA**。您可以为用户提供选项来注册额外的登录安全因素，但仍允许未配置 MFA 的用户登录。如果您使用自适应身份验证，请选择此选项。有关自适应身份验证的更多信息，请参阅[具备威胁防护的高级安全功能](cognito-user-pool-settings-threat-protection.md)。

   1. **无 MFA**。您的用户无法注册其他登录安全要素。

1. 选择您在应用程序中支持的 **MFA 方法**。您可以将**电子邮件消息**、**短信**或 TOTP 生成的**身份验证器应用程序**设置为第二个因素。

1. 如果使用 SMS 文本消息作为第二安全要素，并且没有配置 IAM 角色与 Amazon Simple Notification Service（Amazon SNS）一起使用 SMS 消息，您可以在控制台中创建一个角色。在用户池的**身份验证方法**菜单中，找到**短信**，然后选择**编辑**。您还可以使用允许 Amazon Cognito 代表您向用户发送短信的现有角色。有关更多信息，请参阅 [IAM 角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html)。

   如果使用电子邮件消息作为第二安全因素，但尚未为 Amazon Simple Email Service (Amazon SES) 配置源身份以发送电子邮件消息，则可以在控制台中创建一个。必须选择**使用 SES 发送电子邮件**选项。在用户池的**身份验证方法**菜单中，找到**电子邮件**，然后选择**编辑**。从列表中可用的已验证身份中，选择一个**发件人电子邮件地址**。如果您选择了一个已验证的域（例如 `example.com`），则还必须在该已验证域下配置一个**发件人姓名**，例如 `admin-noreply@example.com`。

1. 选择**保存更改**。

# 短信和电子邮件消息 MFA
<a name="user-pool-settings-mfa-sms-email-message"></a>

短信和电子邮件 MFA 消息确认用户在登录之前对消息目的地具有访问权限。用户确认他们不仅可以访问密码，还可以访问原始用户的短信或电子邮件收件箱。Amazon Cognito 要求用户提供用户池在成功提供用户名和密码后发送的短代码。

用户向其配置文件添加电子邮件地址或电话号码后，短信和电子邮件 MFA 无需额外配置。Amazon Cognito 可以向未经验证的电子邮件地址和电话号码发送消息。当用户完成第一个 MFA 时，Amazon Cognito 会将其电子邮件地址或电话号码标记为已验证。

当拥有 MFA 的用户在您的应用程序中输入他们的用户名和密码时，MFA 身份验证开始。您的应用程序使用调用[InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)或 [AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html)API 请求的 SDK 方法提交这些初始参数。API 响应中的 `ChallengeParameters` 包括一个 `CODE_DELIVERY_DESTINATION` 值，指明发送授权码的位置。在您的应用程序中，显示一个表单，提示用户查看他们的手机，并包括一个输入框用于输入验证码。在他们输入验证码时，请在质询响应 API 请求中提交验证码以完成登录过程。

拥有 MFA 的用户在[托管登录](cognito-user-pools-managed-login.md)页面中使用用户名和密码登录后，系统会自动提示他们输入 MFA 验证码。

用户池使用您的 AWS 账户中的 Amazon Simple Notification Service（Amazon SNS）资源发送 MFA 和其他 Amazon Cognito 通知的短信。同样，用户池使用您账户中的 Amazon Simple Email Service（Amazon SES）发送电子邮件消息。这些关联服务在您的邮件传送 AWS 账单上自行产生费用。在以生产级别的规模发送消息时，还需要满足额外的要求。有关更多信息，请参阅以下链接：
+ [Amazon Cognito 用户池的短信设置](user-pool-sms-settings.md)
+ [全球短信定价](https://aws.amazon.com/sns/sms-pricing/)
+ [Amazon Cognito 用户池的电子邮件设置](user-pool-email.md)
+ [Amazon SES 定价](https://aws.amazon.com/ses/pricing)

## 短信和电子邮件消息 MFA 的注意事项
<a name="user-pool-settings-mfa-sms-email-message-considerations"></a>
+ 要允许用户使用电子邮件 MFA 登录，您的用户池必须具有以下配置选项：

  1. 您的用户池拥有增值版或基础版功能计划。有关更多信息，请参阅 [用户池功能计划](cognito-sign-in-feature-plans.md)。

  1. 您的用户池使用您自己的 Amazon SES 资源发送电子邮件消息。有关更多信息，请参阅 [Amazon SES 电子邮件配置](user-pool-email.md#user-pool-email-developer)。
+ MFA 验证码在您为应用程序客户端设置的**身份验证流程会话持续时间**内有效。

  当您**编辑**应用程序客户端时，需在 Amazon Cognito 控制台的**应用程序客户端**菜单中设置身份验证流程会话的持续时间。您还可以在 `CreateUserPoolClient` 或 `UpdateUserPoolClient` API 请求中设置身份验证流程会话持续时间。有关更多信息，请参阅 [身份验证会话示例](authentication.md#amazon-cognito-user-pools-authentication-flow)。
+ 当用户成功提供 Amazon Cognito 发送到未经验证的电话号码或电子邮件地址的短信或电子邮件中的验证码时，Amazon Cognito 会将相应的属性标记为已验证。
+ 要让用户自助更改与 MFA 关联的电话号码或电子邮件地址的值，他们必须使用访问令牌登录并授权请求。如果他们无法访问他们当前的电话号码或电子邮件地址，则无法登录。您的团队必须在 [AdminUpdateUserAttributes](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminUpdateUserAttributes.html)API 请求中使用管理员 AWS 凭据更改这些值。
+ 在用户池中[配置短信](user-pool-sms-settings.md)后，即无法禁用将短信作为可用的 MFA 因素。

# TOTP 软件令牌 MFA
<a name="user-pool-settings-mfa-totp"></a>

当您在用户池中设置了 TOTP 软件令牌 MFA 时，您的用户通过用户名和密码登录，然后使用 TOTP 完成身份验证。用户设置并验证用户名和密码后，就可以为 MFA 激活 TOTP 软件令牌。如果应用程序使用 Amazon Cognito 托管登录来登录用户，则用户提交用户名和密码，然后在额外的登录页面上提交 TOTP 密码。

您可以在 Amazon Cognito 控制台中为用户池激活 TOTP MFA，也可以使用 Amazon Cognito API 操作来激活。在用户池级别，您可以调用[SetUserPoolMfaConfig](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_SetUserPoolMfaConfig.html)配置 MFA 并启用 TOTP MFA。

**注意**  
如果您没有为用户池激活 TOTP 软件令牌 MFA，则 Amazon Cognito 无法使用此令牌进行关联或验证用户。在这种情况下，用户会收到 `SoftwareTokenMFANotFoundException` 异常，并带有说明 `Software Token MFA has not been enabled by the userPool`。如果您稍后为用户池停用了软件令牌 MFA，则以前已关联并验证 TOTP 令牌的用户可以继续将其用于 MFA。

为用户配置 TOTP 是一个多步骤过程，在此过程中，用户将收到一个秘密代码，它们通过输入一次性密码来验证该代码。接下来，您可以为用户启用 TOTP MFA，或将 TOTP 设置为用户的首选 MFA 方法。

当您将用户池配置为需要 TOTP MFA 并且用户在托管登录中注册应用程序时，Amazon Cognito 会自动执行用户流程。Amazon Cognito 提示您的用户选择 MFA 方法，显示 QR 代码来设置身份验证器应用程序，并验证他们的 MFA 注册。在您允许用户在 SMS 和 TOTP MFA 之间进行选择的用户池中，Amazon Cognito 还为您的用户提供了方法选择。

**重要**  
当您的 AWS WAF Web ACL 与用户池相关联，并且您的 Web ACL 中的规则显示了验证码时，这可能会导致托管登录 TOTP 注册中出现不可恢复的错误。要创建具有 CAPTCHA 操作且不影响托管登录 TOTP 的规则，请参阅[为托管登录 TOTP MFA 配置您的 AWS WAF 网页 ACL](#totp-waf)。有关 AWS WAF 网络 ACLs 和 Amazon Cognito 的更多信息，请参阅。[将 AWS WAF Web ACL 与用户池关联](user-pool-waf.md)

要使用软件开发工具包和 Amazon Co [gnito 用户池 API 在自定义用户界面 AWS 中实现 TOTP MFA，请参](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/Welcome.html)阅。[为用户配置 TOTP MFA](#totp-mfa-set-up-api)

要向用户池添加 MFA，请参阅 [向用户池添加 MFA](user-pool-settings-mfa.md)。

**TOTP MFA 注意事项和限制**

1. Amazon Cognito 通过可生成 TOTP 代码的身份验证器应用程序支持软件令牌 MFA。Amazon Cognito 不支持基于硬件的 MFA。

1. 当您的用户池要求尚未进行配置的用户提供 TOTP 时，您的用户将收到一个一次性访问令牌，应用程序可使用该令牌为用户激活 TOTP MFA。在用户注册了额外的 TOTP 登录安全要素之前，后续的登录尝试将失败。
   + 通过 `SignUp` API 操作或通过托管登录来登录用户池的用户，在完成注册时将收到一次性的令牌。
   + 在您创建用户并且用户设置初始密码后，Amazon Cognito 会从托管登录向用户颁发一次性令牌。如果您为用户设置了永久密码，则 Amazon Cognito 会在用户首次登录时颁发一次性令牌。
   + Amazon Cognito 不会向使用或 API 操作登录的管理员创建的用户发放一次性令牌。[InitiateAuth[AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html)](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)在您的用户成功完成质询来设置初始密码后，或者如果您为用户设置永久密码，Amazon Cognito 会立即向用户提出质询来设置 MFA。

1. 如果用户池中需要 MFA 的用户已收到一次性访问令牌但尚未设置 TOTP MFA，则在设置 MFA 之前，用户无法使用托管登录进行登录。您可以代替访问令牌，而是在请求中使用`MFA_SETUP`质询[InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)或[AssociateSoftwareToken](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AssociateSoftwareToken.html)请求[AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html)中的`session`响应值。

1. 如果您的用户已设置 TOTP，则他们可以将其用于 MFA，即使您以后停用用户池的 TOTP。

1. Amazon Cognito TOTPs 仅接受使用 HMAC 哈希函数生成代码的身份验证器应用程序。SHA1 使用 SHA-256 哈希生成的代码会返回 `Code mismatch` 错误。

## 为用户配置 TOTP MFA
<a name="totp-mfa-set-up-api"></a>

当用户首次登录时，您的应用程序使用他们的一次性访问令牌生成 TOTP 私钥，并以文本或二维码格式将其呈现给用户。您的用户配置其身份验证器应用程序并为后续登录尝试提供 TOTP。您的应用程序或托管登录在 MFA 质询响应中向 Amazon Cognito 提交 TOTP。

在某些情况下，托管登录会提示新用户设置 TOTP 身份验证器。有关更多信息，请参阅[用户运行时的 MFA 逻辑详情](user-pool-settings-mfa.md#user-pool-settings-mfa-user-outcomes)。

**Topics**
+ [关联 TOTP 软件令牌](#user-pool-settings-mfa-totp-associate-token)
+ [验证 TOTP 令牌](#user-pool-settings-mfa-totp-verification)
+ [使用 TOTP MFA 登录](#user-pool-settings-mfa-totp-sign-in)
+ [删除 TOTP 令牌](#user-pool-settings-mfa-totp-remove)

### 关联 TOTP 软件令牌
<a name="user-pool-settings-mfa-totp-associate-token"></a>

要关联 TOTP 令牌，请向用户发送一个必须使用一次性密码来验证的秘密代码。关联令牌需要执行三个步骤。

1. 当您的用户选择 TOTP 软件令牌 MFA 时，[AssociateSoftwareToken](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AssociateSoftwareToken.html)调用返回为用户帐户生成的唯一共享密钥代码。您可以使用访问令牌或会话字符串进行授权 AssociateSoftwareToken 。

1. 您的应用程序向用户呈现私钥或您从私钥生成的二维码。您的用户必须将密钥输入到 TOTP 生成应用程序（如 Google Authenticator）中，方式可以是扫描您的应用程序根据私有密钥生成的二维码，也可以是手动输入该密钥。

1. 您的用户用身份验证器应用程序（例如 Google Authenticator）输入密钥或扫描二维码，该应用程序开始生成代码。

### 验证 TOTP 令牌
<a name="user-pool-settings-mfa-totp-verification"></a>

接下来验证 TOTP 令牌。要求您的用户提供示例代码并将其提供给 Amazon Cognito 服务，以确认用户成功生成 TOTP 代码，如下所示。

1. 您的应用程序会提示用户输入代码，以证明他们已正确设置了身份验证器应用程序。

1. 用户的身份验证器应用程序显示一个临时密码。身份验证器应用程序根据您提供给用户的密钥生成密码。

1. 用户输入他们的临时密码。您的应用程序在 `[VerifySoftwareToken](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_VerifySoftwareToken.html)` API 请求中将临时密码传递给 Amazon Cognito。

1.  Amazon Cognito 保留与用户关联的密钥，并生成 TOTP 并将其与用户提供的 TOTP 进行比较。如果匹配，`VerifySoftwareToken` 返回 `SUCCESS` 响应。

1. Amazon Cognito 将 TOTP 要素与用户关联起来。

1. 如果 `VerifySoftwareToken` 操作返回 `ERROR` 响应，请确保用户的时钟正确且没有超过最大重试次数。Amazon Cognito 接受在尝试前后 30 秒之内的 TOTP 令牌，以容许轻微的时钟偏差。解决问题后，请重试该 VerifySoftwareToken 操作。

### 使用 TOTP MFA 登录
<a name="user-pool-settings-mfa-totp-sign-in"></a>

此时，您的用户可使用基于时间的一次性密码登录。过程如下所述。

1. 用户将输入其用户名和密码来登录客户端应用程序。

1. TOTP MFA 质询被调用，您的应用程序提示用户输入临时密码。

1. 您的用户从关联的 TOTP 生成应用程序获取临时密码。

1. 您的用户在您的客户端应用程序中输入 TOTP 代码。您的应用程序通知 Amazon Cognito 服务以验证该代码。对于每次登录，都[RespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html)应调用以获取对新 TOTP 身份验证质询的响应。

1. 如果令牌通过 Amazon Cognito 验证，则登录成功，您的用户可以继续完成身份验证流程。

### 删除 TOTP 令牌
<a name="user-pool-settings-mfa-totp-remove"></a>

最后，您的应用程序应允许您的用户停用他们的 TOTP 配置。当前，您无法删除用户的 TOTP 软件令牌。要替换用户的软件令牌，请关联并验证新的软件令牌。要为用户停用 TOTP MFA，请致电[SetUserMFAPreference](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_SetUserMFAPreference.html)将您的用户修改为不使用 MFA 或仅使用 SMS MFA。

1. 在您的应用程序中为想要重置 MFA 的用户创建界面。在此界面中提示用户输入密码。

1. 如果 Amazon Cognito 返回 TOTP MFA 质询，请将用户的 MFA 偏好设置更新为。[SetUserMFAPreference](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_SetUserMFAPreference.html)

1. 在您的应用程序中，告知您的用户他们已停用 MFA 并提示他们重新登录。

## 为托管登录 TOTP MFA 配置您的 AWS WAF 网页 ACL
<a name="totp-waf"></a>

当您的 AWS WAF Web ACL 与用户池相关联，并且您的 Web ACL 中的规则显示了验证码时，这可能会导致托管登录 TOTP 注册中出现不可恢复的错误。 AWS WAF 验证码规则*仅*对托管登录和经典托管用户界面中的 TOTP MFA 产生这种影响。SMS MFA 不受影响。

当 CAPTCHA 规则不允许用户完成 TOTP MFA 设置时，Amazon Cognito 会显示以下错误。

由于 WAF captcha，不允许请求。

当你的用户池在后台发出的 [VerifySoftwareToken](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_VerifySoftwareToken.html)API 请求时 AWS WAF 提示输入验证码时，就会出现此错误。[AssociateSoftwareToken](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AssociateSoftwareToken.html)要创建一个包含 CAPTCHA 操作且不影响托管登录页面中 TOTP 的规则，请从您的规则中的 CAPTCHA 操作中排除 `x-amzn-cognito-operation-name` 标头的 `AssociateSoftwareToken` 和 `VerifySoftwareToken` 值。

以下屏幕截图显示了一个示例 AWS WAF 规则，该规则将 CAPTCHA 操作应用于`x-amzn-cognito-operation-name`标头值不为或的所有请求。`AssociateSoftwareToken` `VerifySoftwareToken`

![\[一条 AWS WAF 规则的屏幕截图，该规则将验证码操作应用于x-amzn-cognito-operation-name标头值不为或的所有请求。AssociateSoftwareToken VerifySoftwareToken\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/cup-WAF-rule-TOTP.png)


有关 AWS WAF 网络 ACLs 和 Amazon Cognito 的更多信息，请参阅。[将 AWS WAF Web ACL 与用户池关联](user-pool-waf.md)

# 具备威胁防护的高级安全功能
<a name="cognito-user-pool-settings-threat-protection"></a>

在创建用户池之后，即可使用 Amazon Cognito 控制台中导航菜单中的**威胁防护**。可以打开威胁防护功能并自定义为响应不同风险而执行的操作。或者，您可以使用审计模式收集与检测到的风险相关的指标，而无需应用任何安全缓解措施。在审计模式下，威胁防护会向 Amazon 发布指标 CloudWatch。在 Amazon Cognito 生成其第一个事件后，您即可看到指标。请参阅[查看威胁防护指标](metrics-for-cognito-user-pools.md#user-pool-settings-viewing-threat-protection-metrics)。

威胁防护（此前称为*高级安全功能*）是一组监控用户池中不必要活动的工具，也是用于自动关闭潜在恶意活动的配置工具。威胁防护为标准和自定义身份验证操作提供了不同的配置选项。例如，在设置了额外安全因素时，您可能想向使用可疑自定义身份验证登录的用户发送通知，而阻止使用基本的用户名和密码身份验证且处于相同风险级别的用户。

威胁防护在增值版功能计划中可用。有关更多信息，请参阅 [用户池功能计划](cognito-sign-in-feature-plans.md)。

以下用户池选项是威胁防护的组成部分。

**已泄露的凭证**  
用户将密码重复用于多个用户账户。Amazon Cognito 的已泄露凭证功能可编译公开泄露的用户名和密码数据，并将用户的凭证与泄露的凭证列表进行比较。已泄露凭证的检测还检查常猜测的密码。您可以在用户池的 username-and-password标准身份验证流程中检查凭据是否被泄露。Amazon Cognito 不会在安全远程密码（SRP）或自定义身份验证流程中检测凭证是否泄露。  
您可以选择用于提示检查已泄露凭证的用户操作，以及您希望 Amazon Cognito 采取的应对措施。对于登录、注册和密码更改事件，Amazon Cognito 可以**禁止登录**或**允许登录**。在这两种情况下，Amazon Cognito 都会生成用户活动日志，您可以在其中找到有关该事件的更多信息。  
**了解详情**  
[使用凭证遭泄露检测功能](cognito-user-pool-settings-compromised-credentials.md)

**自适应身份验证**  
Amazon Cognito 可以查看来自用户登录请求的位置和设备信息，并应用自动响应来保护用户池中的用户账户免受可疑活动的侵害。您可以监控用户活动，并自动响应在用户名密码和 SRP 以及自定义身份验证中检测到的风险级别。  
当您激活威胁防护时，Amazon Cognito 会为用户活动分配风险评分。您可以为可疑活动指定自动响应：您可以**需要 MFA**、**禁止登录**，或者只记录活动详细信息和风险评分。您还可以自动发送电子邮件，将可疑活动通知用户，以便他们可以重置密码或采取其他自助操作。  
**了解详情**  
[使用自适应身份验证](cognito-user-pool-settings-adaptive-authentication.md)

**IP 地址允许列表和拒绝列表**  
在**全功能**模式下使用 Amazon Cognito 威胁防护，您可以创建基于 IP 地址的**始终阻止**和**始终允许**例外规则。对于来自**始终阻止**例外列表中 IP 地址的会话，自适应身份验证不会向其分配风险级别，该会话也无法登录您的用户池。  

**有关 IP 地址允许列表和阻止列表的需知信息**
+ **始终阻止**和**始终允许**规则必须使用 CIDR 格式表示，例如 `192.0.2.0/24`（24 位子网掩码）或 `192.0.2.252/32`（单个 IP 地址）。
+  IP 地址在 “**始终阻止**” IP 范围内的设备无法使用基于 SDK 的或托管登录应用程序进行注册或登录，但它们可以使用第三方登录。 IdPs
+ **始终允许**和**始终阻止**列表不会影响令牌刷新。
+ Amazon Cognito 不会对来自**始终允许** IP 范围的设备应用自适应身份验证 MFA 规则，但会应用凭证泄露规则。

**日志导出**  
威胁防护会将用户向您的用户池发起的身份验证请求的详细信息记录到日志中。这些日志包含威胁评估、用户信息以及位置和设备等会话元数据。您可以为这些日志创建外部归档以进行保留和分析。Amazon Cognito 用户池将威胁防护日志导出到亚马逊 S3、 CloudWatch 日志和亚马逊数据 Firehose。有关更多信息，请参阅 [查看和导出用户事件历史记录](cognito-user-pool-settings-adaptive-authentication.md#user-pool-settings-adaptive-authentication-event-user-history)。  
**了解详情**  
[导出威胁防护用户活动日志](exporting-quotas-and-usage.md#exporting-quotas-and-usage-user-activity)

**Topics**
+ [威胁防护的注意事项和限制](#cognito-user-pool-threat-protection-considerations)
+ [在用户池中开启威胁防护](#cognito-user-pool-threat-protection-activating)
+ [威胁防护强制执行概念](#cognito-user-pool-settings-threat-protection-threat-protection-enforcement)
+ [标准身份验证和自定义身份验证的威胁防护](#cognito-user-pool-settings-threat-protection-threat-protection-types)
+ [威胁防护先决条件](#cognito-user-pool-threat-protection-prerequisites)
+ [设置威胁防护](#cognito-user-pool-settings-configure-threat-protection)
+ [使用凭证遭泄露检测功能](cognito-user-pool-settings-compromised-credentials.md)
+ [使用自适应身份验证](cognito-user-pool-settings-adaptive-authentication.md)
+ [在应用程序中收集威胁防护的数据](user-pool-settings-viewing-threat-protection-app.md)

## 威胁防护的注意事项和限制
<a name="cognito-user-pool-threat-protection-considerations"></a>

**不同身份验证流程的威胁防护选项有所不同**  
Amazon Cognito 通过身份验证流程 `USER_PASSWORD_AUTH` 和 `ADMIN_USER_PASSWORD_AUTH` 来支持自适应身份验证和凭证遭泄露检测。您可以仅为 `USER_SRP_AUTH` 启用自适应身份验证。不能将威胁防护与联合身份验证登录一起使用。

**始终屏蔽会增加 IPs 请求配额**  
在您的用户池中阻止来自**始终阻止**例外列表中 IP 地址的请求，可以帮助您的用户池保持在[请求速率配额](https://docs.aws.amazon.com/cognito/latest/developerguide/limits.html#category_operations)以内。

**威胁防护不会应用速率限制**  
一些恶意流量具有请求量大的特征，例如分布式拒绝服务 (DDoS) 攻击。Amazon Cognito 对传入流量应用的风险评分是基于单个请求的，并不考虑请求数。在大批量事件中，即便某些请求与大规模攻击无关，它们仍然可能因为应用层的原因而被赋予风险评分，并触发自动化响应。要对用户池中的容量攻击实施防御，请添加 AWS WAF Web。 ACLs有关更多信息，请参阅 [将 AWS WAF Web ACL 与用户池关联](user-pool-waf.md)。

**威胁防护不影响 M2M 请求**  
客户凭证授予的目的是在与用户帐户无关的情况下进行 machine-to-machine（M2M）授权。威胁防护仅监控用户池中的用户账户和密码。要在 M2M 活动中实现安全功能，请考虑 AWS WAF 用于监控请求率和内容的功能。有关更多信息，请参阅 [将 AWS WAF Web ACL 与用户池关联](user-pool-waf.md)。

## 在用户池中开启威胁防护
<a name="cognito-user-pool-threat-protection-activating"></a>

------
#### [ Amazon Cognito user pools console ]

**为用户池激活威胁防护**

1. 转到 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)。如果出现提示，请输入您的 AWS 凭据。

1. 选择**用户池**。

1. 从列表中选择一个现有用户池，或[创建一个用户池](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-as-user-directory.html)。

1. 如果尚未激活，从**设置**菜单中激活增值版功能计划。

1. 选择**威胁防护**菜单，然后选择**激活**。

1. 选择**保存更改**。

------
#### [ API ]

在[CreateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html)或 [UpdateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPool.html)API 请求中将您的功能计划设置为 Plus。以下部分示例请求正文将威胁防护设置为全功能模式。有关完整的示例请求，请参阅[示例](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html#API_CreateUserPool_Examples)。

```
"UserPoolAddOns": { 
      "AdvancedSecurityMode": "ENFORCED"
   }
```

------

威胁防护是一个总括性术语，指的是一组特征，用于监控用户操作以发现账户盗用的迹象，并自动采取措施来保护受影响的用户账户。当用户使用标准和自定义身份验证流程登录时，您可以对用户应用威胁防护设置。

威胁防护会[生成日志](cognito-user-pool-settings-adaptive-authentication.md#user-pool-settings-adaptive-authentication-event-user-history)，详细说明用户的登录、注销和其他活动。您可以将这些日志导出到第三方系统。有关更多信息，请参阅 [查看和导出用户事件历史记录](cognito-user-pool-settings-adaptive-authentication.md#user-pool-settings-adaptive-authentication-event-user-history)。

## 威胁防护强制执行概念
<a name="cognito-user-pool-settings-threat-protection-threat-protection-enforcement"></a>

威胁防护从*仅限审计*模式开始，在此模式下，用户池会监控用户活动、分配风险级别和生成日志。妥善的做法是，在启用*全功能模式*之前，在仅限审计模式下运行两周或更长时间。全功能模式包括一组针对检测到的风险活动和密码泄露的自动响应措施。在仅限审计模式下，您可以监控 Amazon Cognito 正在执行的威胁评估。您还可以[提供反馈](cognito-user-pool-settings-adaptive-authentication.md#user-pool-settings-adaptive-authentication-feedback)，帮助训练该特征以改进误报和漏报。

您可以在用户池级别配置威胁防护强制执行措施，以覆盖用户池中的所有应用程序客户端，也可以在单个应用程序客户端级别配置威胁防护。应用程序客户端威胁防护配置会覆盖用户池配置。要为应用程序客户端配置威胁防护，请在 Amazon Cognito 控制台中，导航到用户池的**应用程序客户端**菜单中的应用程序客户端设置。在这里，您可以**使用客户端级设置**并配置应用程序客户端专有的强制执行。

此外，您可以分别为标准和自定义身份验证类型配置威胁防护。

## 标准身份验证和自定义身份验证的威胁防护
<a name="cognito-user-pool-settings-threat-protection-threat-protection-types"></a>

配置威胁防护的方式取决于您在用户池和应用程序客户端中进行的身份验证类型。以下每种类型的身份验证都可以有自己的强制执行模式和自动响应。

**标准身份验证**  
*标准身份验证*是指通过用户名密码流程和托管登录实现的用户登录、注销及密码管理。当用户使用托管登录进行登录或使用以下 API `AuthFlow` 参数时，Amazon Cognito 威胁防护会监控操作的风险指标：    
**[InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html#CognitoUserPools-InitiateAuth-request-AuthFlow)**  
`USER_PASSWORD_AUTH`、`USER_SRP_AUTH`。泄露的凭证功能无法在 `USER_SRP_AUTH` 登录时访问密码，并且不会监控或对这个流程中的事件采取行动。  
**[AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html#CognitoUserPools-AdminInitiateAuth-request-AuthFlow)**  
`ADMIN_USER_PASSWORD_AUTH`、`USER_SRP_AUTH`。泄露的凭证特征无法在 `USER_SRP_AUTH` 登录时访问密码，并且不会监控或对这个流程中的事件采取行动。
您可以将标准身份验证的**强制执行模式**设置为**仅限审计**或**全功能**。要禁用标准身份验证的威胁监控，请将威胁防护设置为**没有强制执行**。

**自定义身份验证**  
*自定义身份验证*是使用[自定义质询 Lambda 触发器](user-pool-lambda-challenge.md)的用户登录。您无法在托管登录中进行自定义身份验证。当用户使用 `InitiateAuth` 和 `AdminInitiateAuth` 的 API `AuthFlow` 参数 `CUSTOM_AUTH` 登录时，Amazon Cognito 威胁防护会监控操作的风险指标。  
您可以将自定义身份验证的**强制执行模式**设置为**仅限审计**、**全功能**或**没有强制执行**。**没有强制执行**选项可在不影响其他威胁防护功能的情况下禁用自定义身份验证的威胁监控。

## 威胁防护先决条件
<a name="cognito-user-pool-threat-protection-prerequisites"></a>

在开始之前，您需要：
+ 用户池和应用程序客户端。有关更多信息，请参阅 [用户池入门](getting-started-user-pools.md)。
+ 在 Amazon Cognito 控制台中将多重身份验证（MFA）设置为**可选**,以使用基于风险的自适应身份验证功能。有关更多信息，请参阅 [向用户池添加 MFA](user-pool-settings-mfa.md)。
+ 如果您使用电子邮件通知，请转到 [Amazon SES 控制台](https://console.aws.amazon.com/ses/home)配置并验证要用于通知电子邮件的电子邮件地址或域。有关 Amazon SES 的更多信息，请参阅[在 Amazon SES 中验证身份](https://docs.aws.amazon.com/ses/latest/dg/verify-addresses-and-domains.html)。

## 设置威胁防护
<a name="cognito-user-pool-settings-configure-threat-protection"></a>

请按照以下说明设置用户池威胁防护。

**注意**  
要在 Amazon Cognito 用户池控制台中为应用程序客户端设置不同的威胁防护配置，请从**应用程序客户端**菜单中选择应用程序客户端，然后选择**使用客户端级设置**。

------
#### [ AWS 管理控制台 ]

**为用户池配置威胁防护**

1. 转到 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)。如果出现提示，请输入您的 AWS 凭据。

1. 选择**用户池**。

1. 从列表中选择一个现有用户池，或[创建一个用户池](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-as-user-directory.html)。

1. 选择**威胁防护**菜单，然后选择**激活**。

1. 选择要配置的威胁防护方法：**标准身份验证和自定义身份验证**。您可以为自定义身份验证和标准身份验证设置不同的强制执行模式，但在**全功能**模式下，它们共享自动响应的配置。

1. 选择**编辑**。

1. 选择**强制执行模式**。要立即开始对检测到的风险作出响应，请选择**全功能**并配置针对已泄露凭证和自适应身份验证的自动响应。要在用户级日志中收集信息 CloudWatch，请选择 “**仅审计**”。

   建议在启用操作之前，先将威胁防护保持在审计模式两周。在此期间，Amazon Cognito 可以了解应用程序用户的使用模式，并且您可以提供事件反馈以调整响应。

1. 如果您已选择**仅限审计**，请选择**保存更改**。如果您已选择**全功能**：

   1. 选择是否要进行**自定义**操作或使用 **Cognito 默认设置**响应可疑**已泄露的凭证**。**Cognito 默认设置**：

      1. 检测**登录**、**注册**和**密码更改**中的已泄露的凭证。

      1. 使用**禁止登录**操作响应已泄露的凭证。

   1. 如果您为**已泄露的凭证**选择了**自定义**操作，请选择 Amazon Cognito 将用于**事件检测**的用户池操作，以及您希望 Amazon Cognito 执行的**已泄露凭证的响应**。您可以使用可疑的已泄露凭证进行**禁止登录**或**允许登录**。

   1. 在**自适应身份验证**下，选择如何响应恶意登录尝试。选择是否要进行**自定义**操作或使用 **Cognito 默认设置**响应可疑恶意活动。当您选择 **Cognito 默认设置**时，Amazon Cognito 会阻止所有风险级别的登录，并且不会通知用户。

   1. 如果您针对**自适应身份验证**已选择**自定义操作**，请根据严重性级别选择 Amazon Cognito 对检测到的风险执行的 **自动风险响应**操作。当您针对风险级别分配响应时，您无法为较高风险级别分配限制性较小的响应。您可以为风险级别分配以下响应：

      1. **允许登录** – 不采取任何预防性操作。

      1. **可选 MFA** – 如果用户配置了 MFA，Amazon Cognito 将始终要求用户在登录时提供其它 SMS 或基于时间的一次性密码（TOTP）因素。如果用户没有配置 MFA，他们可以继续正常登录。

      1. **需要 MFA** – 如果用户配置了 MFA，Amazon Cognito 将始终要求用户在登录时提供其它短信或 TOTP 因素。如果用户没有配置 MFA，Amazon Cognito 将提示他们设置 MFA。在您自动要求用户使用 MFA 之前，请在应用程序中配置一种机制来捕获 SMS MFA 的电话号码，或为 TOTP MFA 注册身份验证器应用程序。

      1. **禁止登录** – 阻止用户登录。

      1. **通知用户** – 向用户发送电子邮件，其中包含有关 Amazon Cognito 检测到的风险以及您所采取的响应的信息。您可以为发送的消息自定义电子邮件消息模板。

1. 如果您在上一步骤中选择了**通知用户**，您可以自定义电子邮件发送设置和电子邮件消息模板以进行自适应身份验证。

   1. 在**电子邮件配置**下，选择您希望用于自适应身份验证的 **SES 区域**、**发件人电子邮件地址**、**发件人姓名**和**回复电子邮件地址**。有关将用户池电子邮件消息与 Amazon Simple Email Service 集成的更多信息，请参阅 [Amazon Cognito 用户池的电子邮件设置](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-email.html)。  
![\[用户事件历史记录\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/cup-advanced-security-ses-notification.png)

   1. 展开**电子邮件模板**以自定义包含 HTML 和纯文本版本电子邮件消息的自适应身份验证通知。要了解有关电子邮件消息模板的更多信息，请参阅[消息模板](cognito-user-pool-settings-message-customizations.md#cognito-user-pool-settings-message-templates)。

1. 扩展 **IP 地址例外**以创建**始终允许**或**始终阻止**的列表 IPv4 或 IPv6 地址范围，无论威胁防护风险评估如何，这些地址范围都将始终被允许或阻止。用 [CIDR 表示法](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation)指定 IP 地址范围（例如，192.168.100.0/24）。

1. 选择**保存更改**。

------
#### [ API (user pool) ]

要为用户池设置威胁防护配置，请发送包含参数但不包含`UserPoolId`参数的 [SetRiskConfiguration](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_SetRiskConfiguration.html)API 请求。`ClientId`以下是用户池的一个示例请求正文。此风险配置会根据风险的严重程度执行一系列不断升级的操作，并通知所有风险级别的用户。它对注册操作应用已泄露凭证阻止。

要强制执行此配置，您必须在单独的请求[CreateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html)或 [UpdateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPool.html)API 请求`ENFORCED`中`AdvancedSecurityMode`将设置为。有关占位符模板的更多信息（如本例中的 `{username}`），请参阅 [配置 MFA、身份验证、验证和邀请消息](cognito-user-pool-settings-message-customizations.md)。

```
{
   "AccountTakeoverRiskConfiguration": { 
      "Actions": { 
         "HighAction": { 
            "EventAction": "MFA_REQUIRED",
            "Notify": true
         },
         "LowAction": { 
            "EventAction": "NO_ACTION",
            "Notify": true
         },
         "MediumAction": { 
            "EventAction": "MFA_IF_CONFIGURED",
            "Notify": true
         }
      },
      "NotifyConfiguration": { 
         "BlockEmail": { 
            "Subject": "You have been blocked for suspicious activity",
            "TextBody": "We blocked {username} at {login-time} from {ip-address}."
         },
         "From": "admin@example.com",
         "MfaEmail": { 
            "Subject": "Suspicious activity detected, MFA required",
            "TextBody": "Unexpected sign-in from {username} on device {device-name}. You must use MFA."
         },
         "NoActionEmail": { 
            "Subject": "Suspicious activity detected, secure your user account",
            "TextBody": "We noticed suspicious sign-in activity by {username} from {city}, {country} at {login-time}. If this was not you, reset your password."
         },
         "ReplyTo": "admin@example.com",
         "SourceArn": "arn:aws:ses:us-west-2:123456789012:identity/admin@example.com"
      }
   },
   "CompromisedCredentialsRiskConfiguration": { 
      "Actions": { 
         "EventAction": "BLOCK"
      },
      "EventFilter": [ "SIGN_UP" ]
   },
   "RiskExceptionConfiguration": { 
      "BlockedIPRangeList": [ "192.0.2.0/24","198.51.100.0/24" ],
      "SkippedIPRangeList": [ "203.0.113.0/24" ]
   },
   "UserPoolId": "us-west-2_EXAMPLE"
}
```

------
#### [ API (app client) ]

要为应用程序客户端设置威胁防护配置，请发送包含`UserPoolId`参数和参数的 [SetRiskConfiguration](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_SetRiskConfiguration.html)API 请求。`ClientId`以下是应用程序客户端的一个示例请求正文。此风险配置比用户池配置更为严格，会阻止高风险条目。该配置还将已泄露的凭证阻止应用于注册、登录和密码重置操作。

要强制执行此配置，您必须在单独的请求[CreateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html)或 [UpdateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPool.html)API 请求`ENFORCED`中`AdvancedSecurityMode`将设置为。有关占位符模板的更多信息（如本例中的 `{username}`），请参阅 [配置 MFA、身份验证、验证和邀请消息](cognito-user-pool-settings-message-customizations.md)。

```
{
   "AccountTakeoverRiskConfiguration": { 
      "Actions": { 
         "HighAction": { 
            "EventAction": "BLOCK",
            "Notify": true
         },
         "LowAction": { 
            "EventAction": "NO_ACTION",
            "Notify": true
         },
         "MediumAction": { 
            "EventAction": "MFA_REQUIRED",
            "Notify": true
         }
      },
      "NotifyConfiguration": { 
         "BlockEmail": { 
            "Subject": "You have been blocked for suspicious activity",
            "TextBody": "We blocked {username} at {login-time} from {ip-address}."
         },
         "From": "admin@example.com",
         "MfaEmail": { 
            "Subject": "Suspicious activity detected, MFA required",
            "TextBody": "Unexpected sign-in from {username} on device {device-name}. You must use MFA."
         },
         "NoActionEmail": { 
            "Subject": "Suspicious activity detected, secure your user account",
            "TextBody": "We noticed suspicious sign-in activity by {username} from {city}, {country} at {login-time}. If this was not you, reset your password."
         },
         "ReplyTo": "admin@example.com",
         "SourceArn": "arn:aws:ses:us-west-2:123456789012:identity/admin@example.com"
      }
   },
   "ClientId": "1example23456789",
   "CompromisedCredentialsRiskConfiguration": { 
      "Actions": { 
         "EventAction": "BLOCK"
      },
      "EventFilter": [ "SIGN_UP", "SIGN_IN", "PASSWORD_CHANGE" ]
   },
   "RiskExceptionConfiguration": { 
      "BlockedIPRangeList": [ "192.0.2.1/32","192.0.2.2/32" ],
      "SkippedIPRangeList": [ "192.0.2.3/32","192.0.2.4/32" ]
   },
   "UserPoolId": "us-west-2_EXAMPLE"
}
```

------

# 使用凭证遭泄露检测功能
<a name="cognito-user-pool-settings-compromised-credentials"></a>

Amazon Cognito 可以检测用户的用户名和密码是否已在别处遭盗用。这种情况可能出现在用户在多个站点重复使用凭证时或它们使用不安全的密码时。Amazon Cognito 通过托管登录和 Amazon Cognito API 检查使用用户名和密码登录的[本地用户](cognito-terms.md#terms-localuser)。

在 Amazon Cognito 控制台的**威胁防护**菜单中，您可以配置**已泄露的凭证**。配置**事件检测**以选择要监控的用户事件，以查看是否有已泄露的凭证。配置**已泄露凭证的响应**，以选择在检测到已泄露的凭证时是允许还是阻止用户。Amazon Cognito 可以在登录、注册和密码更改期间检查是否有已泄露的凭证。

选择 “**允许登录**” 后，您可以查看 Amazon CloudWatch Logs 以监控 Amazon Cognito 对用户事件所做的评估。有关更多信息，请参阅 [查看威胁防护指标](metrics-for-cognito-user-pools.md#user-pool-settings-viewing-threat-protection-metrics)。当您选择**禁止登录**时，Amazon Cognito 会阻止使用已泄露的凭证的用户登录。当 Amazon Cognito 阻止用户登录时，它将用户的 [https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UserType.html](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UserType.html) 设置为 `RESET_REQUIRED`。具有 `RESET_REQUIRED` 状态的用户必须先更改密码，然后才能再次登录。

已泄露的凭证可针对以下用户活动检查密码。

**注册**  
您的用户池会检查用户在[SignUp](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_SignUp.html)操作中以及托管登录的注册页面中传输的密码，以确定是否存在泄露迹象。

**登录**  
您的用户池会检查用户在基于密码的登录中提交的密码是否存在泄露迹象。Amazon Cognito 可以在[AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html)两者中查看`USER_PASSWORD_AUTH`流[InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)入、流入和`USER_AUTH`流入的`PASSWORD`选项。`ADMIN_USER_PASSWORD_AUTH`  
当前，对于采用安全远程密码（SRP）流程的登录操作，Amazon Cognito 不会检查是否有已泄露的凭证。SRP 在登录期间发送经过哈希处理的密码证明。Amazon Cognito 无法在内部访问密码，因此，它只能评估您的客户端以纯文本形式传递给它的密码。

**密码重置**  
在使用[ConfirmForgotPassword](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ConfirmForgotPassword.html)自助密码重置操作设置新用户密码的操作中，您的用户池会检查是否存在泄露迹象。此操作所需的代码由[ForgotPassword](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ForgotPassword.html)和生成[AdminResetUserPassword](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminResetUserPassword.html)。  
被泄露的凭据无法检查管理员设置的临时或永久密码。[AdminSetUserPassword](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminSetUserPassword.html)但是，使用临时密码时，您的用户池会根据[RespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html)和中对`NEW_PASSWORD_REQUIRED`质询的响应来检查密码[AdminRespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminRespondToAuthChallenge.html)。

要向用户池添加已泄露的凭证保护，请参阅 [具备威胁防护的高级安全功能](cognito-user-pool-settings-threat-protection.md)。

# 使用自适应身份验证
<a name="cognito-user-pool-settings-adaptive-authentication"></a>

借助自适应身份验证，可以将用户池配置为阻止可疑登录，或为响应增加的风险级别添加第二安全要素身份验证。对于每次登录尝试，Amazon Cognito 都会生成一个风险分数来表示登录请求来自遭盗用源的可能性。此风险评分基于您的应用程序提供的设备和用户因素，以及 Amazon Cognito 从请求中得出的其他因素。会影响 Amazon Cognito 风险评估的一些因素包括：IP 地址、用户代理以及与其他登录尝试之间的地理距离。当 Amazon Cognito 检测到用户会话中存在风险且用户尚未选择多重身份验证（MFA）方法时，自适应身份验证可以为用户池中的用户开启或要求 MFA。当您为用户激活 MFA 时，无论您如何配置自适应身份验证，他们都会收到在身份验证期间提供或设置第二因素的质询。从用户的角度来看，您的应用程序可以帮助他们设置 MFA，也可以选择让 Amazon Cognito 阻止他们再次登录，直到他们配置了附加因素。

Amazon Cognito 向亚马逊发布了有关登录尝试、其风险等级和挑战失败的指标。 CloudWatch有关更多信息，请参阅 [查看威胁防护指标](metrics-for-cognito-user-pools.md#user-pool-settings-viewing-threat-protection-metrics)。

要向用户池添加自适应身份验证，请参阅 [具备威胁防护的高级安全功能](cognito-user-pool-settings-threat-protection.md)。

**Topics**
+ [自适应身份验证概览](#security-cognito-user-pool-settings-adaptive-authentication-overview)
+ [将用户设备和会话数据添加到 API 请求](#user-pool-settings-adaptive-authentication-device-fingerprint)
+ [查看和导出用户事件历史记录](#user-pool-settings-adaptive-authentication-event-user-history)
+ [提供事件反馈](#user-pool-settings-adaptive-authentication-feedback)
+ [发送通知消息](#user-pool-settings-adaptive-authentication-messages)

## 自适应身份验证概览
<a name="security-cognito-user-pool-settings-adaptive-authentication-overview"></a>

在 Amazon Cognito 控制台中的**威胁防护**菜单中，您可以选择自适应身份验证的设置，包括在不同风险级别下采取什么操作，以及向用户发送的通知消息的自定义设置。您可以为所有应用程序客户端分配全局威胁防护配置，但将客户端级配置应用于各个应用程序客户端。

Amazon Cognito 自适应身份验证为每个用户会话分配以下风险级别之一：**高**、**中**、**低**或**无风险**。

将**强制执行方法**从**仅限审计**更改为**全功能**时，请仔细斟酌您的选项。您对风险等级应用的自动响应会影响 Amazon Cognito 为具有相同特征的后续用户会话分配的风险等级。例如，在您选择不采取任何操作或**允许**之后，对于 Amazon Cognito 最初评估为高风险的用户会话，Amazon Cognito 会认为类似会话的风险较低。


**对于每个风险级别，您可以选择以下选项：**  

|  Option  |  Action  | 
| --- | --- | 
| 允许 | 用户无需额外安全要素即可登录。 | 
| 可选 MFA | 已配置第二安全要素的用户需要完成第二安全要素质询才能登录。用于 SMS 的电话号码和 TOTP 软件令牌是可供使用的第二个安全要素。未配置第二个因素的用户只能使用一组凭证登录。 | 
| 需要 MFA | 已配置第二安全要素的用户需要完成第二安全要素质询才能登录。Amazon Cognito 阻止未配置第二个安全要素的用户登录。 | 
| 阻止 | Amazon Cognito 阻止指定风险级别下的所有登录尝试。 | 

**注意**  
您无需验证手机号码即可将其用于 SMS 来作为第二个身份验证要素。

## 将用户设备和会话数据添加到 API 请求
<a name="user-pool-settings-adaptive-authentication-device-fingerprint"></a>

当您使用 API 对用户进行注册、登录和重置密码时，可以收集用户会话的相关信息并将其传递给 Amazon Cognito 威胁防护。此信息包括用户的 IP 地址和唯一的设备标识符。

您可能在用户和 Amazon Cognito 之间有中间网络设备，例如代理服务或应用程序服务器。您可以收集用户的上下文数据并将其传递给 Amazon Cognito，以便自适应身份验证根据用户端点（而不是服务器或代理）的特征来计算风险。如果您的客户端应用程序直接调用 Amazon Cognito API 操作，自适应身份验证会自动记录源 IP 地址。但是，它不会记录其他设备信息（例如 `user-agent`），除非您也收集设备指纹。

使用 Amazon Cognito 上下文数据收集库生成这些数据，然后使用和参数将其提交给 Amazon Cognito 威胁防护。[ContextData[UserContextData](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UserContextDataType.html)](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ContextDataType.html)上下文数据收集库包含在 AWS SDKs。有关更多信息，请参阅 [将 Amazon Cognito 身份验证和授权与 Web 和移动应用程序集成](cognito-integrate-apps.md)。如果您有增值版功能计划，则可以提交 `ContextData`。有关更多信息，请参阅 [设置威胁防护](cognito-user-pool-settings-threat-protection.md#cognito-user-pool-settings-configure-threat-protection)。

当您从应用程序服务器调用以下经过 Amazon Cognito 身份验证的 API 操作时，请在 `ContextData` 参数中传递用户设备的 IP。此外，请传递服务器名称、服务器路径和编码的设备指纹数据。
+ [AdminInitiateAuth ](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html)
+ [AdminRespondToAuthChallenge ](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminRespondToAuthChallenge.html)

当您调用 Amazon Cognito 未经身份验证的 API 操作时，您可以将 `UserContextData` 提交到 Amazon Cognito 威胁防护。此数据在 `EncodedData` 参数中包括设备指纹。如果您符合以下条件，也可以在 `UserContextData` 中提交 `IpAddress` 参数：
+ 您的用户池使用增值版功能计划。有关更多信息，请参阅 [用户池功能计划](cognito-sign-in-feature-plans.md)。
+ 您的应用程序客户端具有客户端密钥。有关更多信息，请参阅 [特定于应用程序的应用程序客户端设置](user-pool-settings-client-apps.md)。
+ 您已在应用程序客户端中激活 **接受其他用户上下文数据**。有关更多信息，请参阅 [接受额外的用户上下文数据（AWS 管理控制台）](#user-pool-settings-adaptive-authentication-accept-user-context-data)。

您的应用程序可以在以下 Amazon Cognito 未经验证的 API 操作中，使用编码的设备指纹数据和用户设备的 IP 地址填充 `UserContextData` 参数。
+ [InitiateAuth ](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)
+ [RespondToAuthChallenge ](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html)
+ [SignUp ](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_SignUp.html)
+ [ConfirmSignUp ](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ConfirmSignUp.html)
+ [ForgotPassword ](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ForgotPassword.html)
+ [ConfirmForgotPassword ](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ConfirmForgotPassword.html)
+ [ResendConfirmationCode ](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ResendConfirmationCode.html)

### 接受额外的用户上下文数据（AWS 管理控制台）
<a name="user-pool-settings-adaptive-authentication-accept-user-context-data"></a>

激活**接受其他用户上下文数据**功能后，用户池在 `UserContextData` 参数中接受 IP 地址。在以下情况下，您无需激活此功能：
+ 您的用户只能使用经过身份验证的 API 操作（例如）登录 [AdminInitiateAuth ](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html)，并且您使用`ContextData`参数。
+ 您只希望未经身份验证的 API 操作向 Amazon Cognito 威胁防护发送设备指纹，而不是 IP 地址。

在 Amazon Cognito 控制台中按如下方式更新应用程序客户端，以添加对其他用户上下文数据的支持。

1. 登录 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)。

1. 在导航窗格中，选择 **管理您的用户池**，然后选择要编辑的用户池。

1. 选择**应用程序客户端**菜单。

1. 选择或创建一个应用程序客户端。有关更多信息，请参阅[配置用户池应用程序客户端](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-app-idp-settings.html)。

1. 从**应用程序客户端信息**容器中选择**编辑**。

1. 在应用程序客户端的**高级身份验证设置**下，选择**接受其他用户上下文数据**。

1. 选择**保存更改**。

要将您的应用程序客户端配置为接受 Amazon Cognito API 中的用户情境数据，请在[CreateUserPoolClient](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPoolClient.html)或`EnablePropagateAdditionalUserContextData`[UpdateUserPoolClient](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPoolClient.html)请求`true`中设置为。有关在 Web 或移动应用程序中使用威胁防护功能的信息，请参阅[在应用程序中收集威胁防护的数据](user-pool-settings-viewing-threat-protection-app.md)。当您的应用程序从服务器调用 Amazon Cognito 时，从客户端收集用户上下文数据。以下是使用 JavaScript SDK 方法的示例`getData`。

```
var EncodedData = AmazonCognitoAdvancedSecurityData.getData(username, userPoolId, clientId);
```

在设计应用程序以使用自适应身份验证时，建议您将最新的 Amazon Cognito 开发工具包集成到应用程序中。最新版本的开发工具包收集设备指纹信息，如设备 ID、模型和时区。有关 Amazon Cognito 的更多信息 SDKs，请参阅[安装用户池软件开发](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-sdk-links.html)工具包。Amazon Cognito 威胁防护功能只为应用程序以正确格式提交的事件保存和分配风险评分。如果 Amazon Cognito 返回错误响应，请检查您的请求是否包含有效的密钥哈希以及该`IPaddress`参数是否有效 IPv4 或 IPv6 地址。

**`ContextData` 和 `UserContextData` 资源**
+ AWS Amplify 适用于 Android 的 SDK：[GetUserContextData](https://github.com/aws-amplify/aws-sdk-android/blob/main/aws-android-sdk-cognitoidentityprovider/src/main/java/com/amazonaws/mobileconnectors/cognitoidentityprovider/CognitoUserPool.java#L626)
+ AWS Amplify 适用于 iOS 的 SDK：[userContextData](https://github.com/aws-amplify/aws-sdk-ios/blob/d3cd4fa0086b526f2f5c9c6c58880c9da7004c66/AWSCognitoIdentityProviderASF/AWSCognitoIdentityProviderASF.m#L21)
+ JavaScript: [amazon-cognito-advanced-security-](https://amazon-cognito-assets.us-east-1.amazoncognito.com/amazon-cognito-advanced-security-data.min.js) data.min.js

## 查看和导出用户事件历史记录
<a name="user-pool-settings-adaptive-authentication-event-user-history"></a>

当您启用威胁防护时，Amazon Cognito 会为用户的每个身份验证事件生成日志。默认情况下，您可以在 Amazon Cognito 控制台的 “**用户**” 菜单中或[AdminListUserAuthEvents](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminListUserAuthEvents.html)通过 API 操作查看用户日志。您也可以将这些事件导出到外部系统，例如 CloudWatch 日志、Amazon S3 或 Amazon Data Firehose。导出特征使您自己的安全分析系统更容易访问有关应用程序中用户活动的安全信息。

**Topics**
+ [查看用户事件历史记录（AWS 管理控制台）](#user-pool-settings-adaptive-authentication-event-user-history-console)
+ [查看用户事件历史记录（API/CLI）](#user-pool-settings-adaptive-authentication-event-user-history-api-cli)
+ [导出用户身份验证事件](#user-pool-settings-adaptive-authentication-event-user-history-exporting)

### 查看用户事件历史记录（AWS 管理控制台）
<a name="user-pool-settings-adaptive-authentication-event-user-history-console"></a>

要查看某个用户的登录历史记录，您可以在 Amazon Cognito 控制台的**用户**菜单中选择该用户。Amazon Cognito 会将用户事件历史记录保留两年。

![\[用户事件历史记录\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/cup-advanced-security-event-history.png)


每个登录事件都有一个事件 ID。该事件还包含对应的上下文数据，如位置、设备详细信息和风险检测结果。

您还可以将事件 ID 与 Amazon Cognito 在记录事件时颁发的令牌关联起来。ID 和访问令牌在其有效载荷中包含此事件 ID。Amazon Cognito 还将刷新令牌的使用与原始事件 ID 相关联。您可以通过原始事件 ID 追溯到导致颁发 Amazon Cognito 令牌的登录事件的事件 ID。您可以跟踪系统中的令牌在特定身份验证事件中的使用。有关更多信息，请参阅 [了解用户池 JSON 网络令牌 (JWTs)](amazon-cognito-user-pools-using-tokens-with-identity-providers.md)。

### 查看用户事件历史记录（API/CLI）
<a name="user-pool-settings-adaptive-authentication-event-user-history-api-cli"></a>

[您可以使用 Amazon Cognito API 操作[AdminListUserAuthEvents](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminListUserAuthEvents.html)或带有-events 的 AWS Command Line Interface (AWS CLI) 来查询用户事件历史记录。admin-list-user-auth](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/admin-list-user-auth-events.html)

------
#### [ AdminListUserAuthEvents request ]

以下请求正文 `AdminListUserAuthEvents` 返回一个用户的最新活动日志。

```
{
  "UserPoolId": "us-west-2_EXAMPLE", 
  "Username": "myexampleuser", 
  "MaxResults": 1
}
```

------
#### [ admin-list-user-auth-events request ]

以下请求 `admin-list-user-auth-events` 返回一个用户的最新活动日志。

```
aws cognito-idp admin-list-user-auth-events --max-results 1 --username myexampleuser --user-pool-id us-west-2_EXAMPLE
```

------
#### [ Response ]

Amazon Cognito 对两个请求返回相同的 JSON 响应正文。以下是未发现包含风险因素的托管登录事件的响应示例：

```
{
    "AuthEvents": [
        {
            "EventId": "[event ID]",
            "EventType": "SignIn",
            "CreationDate": "[Timestamp]",
            "EventResponse": "Pass",
            "EventRisk": {
                "RiskDecision": "NoRisk",
                "CompromisedCredentialsDetected": false
            },
            "ChallengeResponses": [
                {
                    "ChallengeName": "Password",
                    "ChallengeResponse": "Success"
                }
            ],
            "EventContextData": {
                "IpAddress": "192.168.2.1",
                "DeviceName": "Chrome 125, Windows 10",
                "Timezone": "-07:00",
                "City": "Bellevue",
                "Country": "United States"
            }
        }
    ],
    "NextToken": "[event ID]#[Timestamp]"
}
```

------

### 导出用户身份验证事件
<a name="user-pool-settings-adaptive-authentication-event-user-history-exporting"></a>

配置您的用户池以将用户事件从威胁防护导出到外部系统。支持的外部系统（Amazon S3、 CloudWatch Logs 和 Amazon Data Firehose）可能会增加您发送或检索的数据 AWS 账单的费用。有关更多信息，请参阅 [导出威胁防护用户活动日志](exporting-quotas-and-usage.md#exporting-quotas-and-usage-user-activity)。

------
#### [ AWS 管理控制台 ]

1. 登录 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)。

1. 选择**用户池**。

1. 从列表中选择一个现有用户池，或[创建一个用户池](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-as-user-directory.html)。

1. 选择**日志流式传输**菜单。选择**编辑**。

1. 在**日志记录状态**下，选中**激活用户活动日志导出**旁边的复选框。

1. 在**日志目标**下，选择要处理日志 AWS 服务 的：**CloudWatch 日志组**、**Amazon Data Firehose 流**或 **S3 存储**桶。

1. 您的选择将使用相应的资源类型填入资源选择器。从列表中选择日志组、流或存储桶。您也可以选择**创建**按钮，导航到所选服务的 AWS 管理控制台 并创建新资源。

1. 选择**保存更改**。

------
#### [ API ]

为您的用户活动日志选择一种目标类型。

以下是将 Firehose 流设置为日志目标的示例 `SetLogDeliveryConfiguration` 请求正文。

```
{
   "LogConfigurations": [
      {
         "EventSource": "userAuthEvents",
         "FirehoseConfiguration": {
            "StreamArn": "arn:aws:firehose:us-west-2:123456789012:deliverystream/example-user-pool-activity-exported"
         },
         "LogLevel": "INFO"
      }
   ],
   "UserPoolId": "us-west-2_EXAMPLE"
}
```

以下是将 Amazon S3 存储桶设置为日志目标的示例 `SetLogDeliveryConfiguration` 请求正文。

```
{
   "LogConfigurations": [
      {
         "EventSource": "userAuthEvents",
         "S3Configuration": { 
            "BucketArn": "arn:aws:s3:::amzn-s3-demo-logging-bucket"
         },
         "LogLevel": "INFO"
      }
   ],
   "UserPoolId": "us-west-2_EXAMPLE"
}
```

以下是将 CloudWatch 日志组设置为日志目标的`SetLogDeliveryConfiguration`请求正文示例。

```
{
   "LogConfigurations": [
      {
         "EventSource": "userAuthEvents",
         "CloudWatchLogsConfiguration": { 
            "LogGroupArn": "arn:aws:logs:us-west-2:123456789012:log-group:DOC-EXAMPLE-LOG-GROUP"
         },
         "LogLevel": "INFO"
      }
   ],
   "UserPoolId": "us-west-2_EXAMPLE"
}
```

------

## 提供事件反馈
<a name="user-pool-settings-adaptive-authentication-feedback"></a>

事件反馈实时影响风险评估，并随着时间的推移改进风险评估算法。您可以通过 Amazon Cognito 控制台和 API 操作提供有关登录尝试有效性的反馈。

**注意**  
您的事件反馈会影响 Amazon Cognito 为具有相同特征的后续用户会话分配的风险等级。

在 Amazon Cognito 控制台中，从**用户**菜单中选择一个用户，然后选择**提供事件反馈**。您可以查看事件详细信息，并选择**设为有效**或**设为无效**。

控制台在**用户**菜单中的“用户详细信息”中列出了登录历史记录。您可以选择某个条目来将事件标记为有效或无效。您还可以通过用户池 API 操作和 AWS CLI 命令 [admin-update-auth-event-fe [AdminUpdateAuthEventFeedback](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminUpdateAuthEventFeedback.html)edback 提供反馈](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/admin-update-auth-event-feedback.html)。

当您在 Amazon Cognito 控制台中选择**设为有效**或在 API 中提供 `valid` 的 `FeedbackValue` 值时，您告诉 Amazon Cognito 您信任某个用户会话（Amazon Cognito 已在其中评估了某种风险等级）。当您在 Amazon Cognito 控制台中选择**设为无效**或在 API 中提供 `invalid` 的 `FeedbackValue` 值时，您告诉 Amazon Cognito 您不信任某个用户会话，或者您不认为 Amazon Cognito 评估的风险等级足够高。

## 发送通知消息
<a name="user-pool-settings-adaptive-authentication-messages"></a>

通过威胁防护功能，Amazon Cognito 可以通知您的用户存在有风险的登录尝试。Amazon Cognito 还可以提示用户选择链接以指示登录是有效还是无效。Amazon Cognito 使用此反馈来提高用户池的风险检测准确性。

**注意**  
只有当用户的操作生成自动风险响应时，Amazon Cognito 才会向其发送通知消息：阻止登录、允许登录、将 MFA 设置为可选或要求 MFA。某些请求可能会被分配一定风险级别，但不会生成自适应身份验证的自动风险响应；对于这些请求，您的用户池不会发送通知。例如，错误的密码可能会被记录并附带风险评级，但 Amazon Cognito 的响应是直接拒绝登录，而不是应用自适应身份验证规则。

在**自动风险响应**部分，对低、中或高风险案例选择**通知用户**。

![\[通知用户\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/cup-adaptive-auth.png)


无论您的用户是否验证了电子邮件地址，Amazon Cognito 都会向他们发送电子邮件通知。

您可以自定义通知电子邮件消息，并提供这些消息的纯文本和 HTML 版本。要自定义您的电子邮件通知，请在威胁防护配置中，从**自适应身份验证消息**中打开**电子邮件模板**。要了解有关电子邮件模板的更多信息，请参阅 [消息模板](cognito-user-pool-settings-message-customizations.md#cognito-user-pool-settings-message-templates)。

# 在应用程序中收集威胁防护的数据
<a name="user-pool-settings-viewing-threat-protection-app"></a>

Amazon Cognito [自适应身份验证](cognito-user-pool-settings-adaptive-authentication.md)根据用户登录尝试的上下文详细信息评估账户盗用尝试的风险等级。您的应用程序必须向 API 请求添加*上下文数据*，这样 Amazon Cognito 威胁防护功能才能更准确地评估风险。上下文数据是诸如 IP 地址、浏览器代理、设备信息和请求标头之类的信息，这些信息提供有关用户如何连接到用户池的上下文信息。

向 Amazon Cognito 提交此上下文的应用程序的核心责任是向用户池发送身份验证请求中的一个 `EncodedData` 参数。要将这些数据添加到您的请求中，您可以使用软件开发工具包实现 Amazon Cognito，该软件开发工具包可以自动为您生成这些信息，也可以实现一个适用于 JavaScript iOS 或 Android 的模块来收集这些数据。必须实现直接向 Amazon Cognito 发出请求的@@ *仅限客户端*的应用程序。 AWS Amplify SDKs具有中间服务器或 API 组件的*客户端-服务器*应用程序必须实施单独的 SDK 模块。

在以下情况下，您的身份验证前端无需任何额外配置即可管理用户上下文数据的收集：
+ 托管登录会自动收集上下文数据并将其提交给威胁防护。
+ 所有 AWS Amplify 库的身份验证方法中都内置了上下文数据集合。

## 使用 Amplify 在仅限客户端的应用程序中提交用户上下文数据
<a name="user-pool-settings-viewing-threat-protection-app-amplify"></a>

![\[Amplify 应用程序中收集数据以进行威胁防护的概览图。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/user-pools-asf-amplify-data-collection.png)


Amplify SDKs 支持直接通过 Amazon Cognito 进行身份验证的移动客户端。此类客户端直接向 Amazon Cognito 公共 API 操作发出 API 请求。默认情况下，Amplify 客户端会自动收集上下文数据以进行威胁防护。

带的 Amplify 应用程序是个 JavaScript 例外。它们需要添加一个用于收集用户上下文数据的[JavaScript 模块](#user-pool-settings-viewing-threat-protection-app-additional-resources-js)。

通常，此配置中的应用程序使用未经身份验证的 API 操作，例如[InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)和。[RespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html)该[UserContextData](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UserContextDataType.html)对象有助于更准确地评估这些操作的风险。Amplify SDKs 将设备和会话信息添加到的`EncodedData`参数中。`UserContextData`

## 在客户端-服务器应用程序中收集上下文数据
<a name="user-pool-settings-viewing-threat-protection-app-server-side"></a>

某些应用程序的前端层用于收集用户身份验证数据，应用程序的后端层用于将身份验证请求提交到 Amazon Cognito。在由微服务支持的 Web 服务器和应用程序中，这是一种常见的架构。在这些应用程序中，必须导入公共上下文数据收集库。

![\[中包含威胁防护上下文数据的服务器端身份验证概述。 JavaScript\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/user-pools-asf-non-amplify-data-collection.png)


通常，此配置中的应用服务器使用经过身份验证的 API 操作，例如[AdminInitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html)和[AdminRespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminRespondToAuthChallenge.html)。该[ContextData](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html#CognitoUserPools-AdminInitiateAuth-request-ContextData)对象可帮助 Amazon Cognito 更准确地评估这些操作的风险。`ContextData` 的内容是您的前端传递给服务器的编码数据，以及用户向服务器发出的 HTTP 请求中的其他详细信息。这些额外的上下文详细信息（例如 HTTP 标头和 IP 地址）为您的应用程序服务器提供了用户环境的特性。

您的应用服务器也可能使用未经身份验证的 API 操作（如[InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)和）进行登录。[RespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html)该[UserContextData](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html#CognitoUserPools-InitiateAuth-request-UserContextData)对象为这些操作中的威胁防护风险分析提供信息。可用的公共上下文数据收集库中的操作将安全信息添加到身份验证请求的 `EncodedData` 参数中。此外，将您的用户池配置为接受其他上下文数据，并将用户的源 IP 添加到 `UserContextData` 的 `IpAddress` 参数中。

**将上下文数据添加到客户端-服务器应用程序**

1. 在您的前端应用程序中，使用 iO [S、Android 或 JavaScript ](#user-pool-settings-viewing-threat-protection-app-additional-resources)模块从客户端收集经过编码的上下文数据。

1. 将编码后的数据和身份验证请求的详细信息传递给应用程序服务器。

1. 在应用程序服务器中，从 HTTP 请求中提取用户的 IP 地址、相关 HTTP 标头、请求的服务器名称和请求的路径。将这些值填充到你向 Amazon Cognito 发出 API 请求的[ContextData](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminInitiateAuth.html#CognitoUserPools-AdminInitiateAuth-request-ContextData)参数中。

1. 使用您的 SDK 模块收集的已编码设备数据填充您的 API 请求中的 `ContextData` 的 `EncodedData` 参数。将此上下文数据添加到身份验证请求中。

## 客户端-服务器应用程序的上下文数据库
<a name="user-pool-settings-viewing-threat-protection-app-additional-resources"></a>

### JavaScript
<a name="user-pool-settings-viewing-threat-protection-app-additional-resources-js"></a>

`amazon-cognito-advanced-security-data.min.js` 模块收集了 `EncodedData`，您可以将其传递给应用程序服务器。

将该`amazon-cognito-advanced-security-data.min.js`模块添加到您的 JavaScript 配置中。`<region>`替换为以下 AWS 区域 列表中的：`us-east-1`、`us-east-2`、`us-west-2``eu-west-1`、`eu-west-2`、或`eu-central-1`。

```
<script src="https://amazon-cognito-assets.<region>.amazoncognito.com/amazon-cognito-advanced-security-data.min.js"></script>
```

要生成可在`EncodedData`参数中使用的`encodedContextData`对象，请将以下内容添加到您的 JavaScript 应用程序源中：

```
var encodedContextData = AmazonCognitoAdvancedSecurityData.getData(_username, _userpoolId, _userPoolClientId);
```

### iOS/Swift
<a name="user-pool-settings-viewing-threat-protection-app-additional-resources-ios"></a>

要生成上下文数据，iOS 应用程序可以集成适用于 iO [S 的移动 SDK](https://github.com/aws-amplify/aws-sdk-ios/tree/main) 模块 [AWSCognitoIdentityProviderASF](https://github.com/aws-amplify/aws-sdk-ios/tree/main/AWSCognitoIdentityProviderASF)。

要收集经过编码的上下文数据以进行威胁防护，请将以下代码段添加到您的应用程序中：

```
import AWSCognitoIdentityProviderASF

let deviceId = getDeviceId()
let encodedContextData = AWSCognitoIdentityProviderASF.userContextData(
                            userPoolId, 
                            username: username, 
                            deviceId: deviceId, 
                            userPoolClientId: userPoolClientId)
                                
/**
 * Reuse DeviceId from keychain or generate one for the first time.
 */
func getDeviceId() -> String {
    let deviceIdKey = getKeyChainKey(namespace: userPoolId, key: "AWSCognitoAuthAsfDeviceId")
    
   if let existingDeviceId = self.keychain.string(forKey: deviceIdKey) {
        return existingDeviceId
    }

    let newDeviceId = UUID().uuidString
    self.keychain.setString(newDeviceId, forKey: deviceIdKey)
    return newDeviceId
}

/**
 * Get a namespaced keychain key given a namespace and key
 */    
func getKeyChainKey(namespace: String, key: String) -> String {
    return "\(namespace).\(key)"
}
```

### Android
<a name="user-pool-settings-viewing-threat-protection-app-additional-resources-android"></a>

要生成上下文数据，安卓应用可以集成[适用于安卓的移动 SDK](https://github.com/aws-amplify/aws-sdk-android/tree/main) 模块 [aws-android-sdk-cognitoidentityprovider-asf](https://github.com/aws-amplify/aws-sdk-android/tree/main/aws-android-sdk-cognitoidentityprovider-asf)。

要收集经过编码的上下文数据以进行威胁防护，请将以下代码段添加到您的应用程序中：

```
UserContextDataProvider provider = UserContextDataProvider.getInstance();
// context here is android application context.
String encodedContextData = provider.getEncodedContextData(context, username, userPoolId, userPoolClientId);
```

# 将 AWS WAF Web ACL 与用户池关联
<a name="user-pool-waf"></a>

AWS WAF 是 Web 应用程序防火墙。借助 AWS WAF 网络访问控制列表 (Web ACL)，您可以保护您的用户池免受对经典托管用户界面、托管登录和 Amazon Cognito API 服务终端节点的不必要请求。Web ACL 使您可以对用户池响应的所有 HTTPS Web 请求进行精细控制。有关 AWS WAF Web 的更多信息 ACLs，请参阅《*AWS WAF 开发人员指南》*中的[管理和使用 Web 访问控制列表 (Web ACL)](https://docs.aws.amazon.com/waf/latest/developerguide/web-acl.html)。

当您的 AWS WAF Web ACL 与用户池关联时，Amazon Cognito 会将您的用户请求中选定的非机密标头和内容转发到。 AWS WAF AWS WAF 检查请求的内容，将其与您在网页 ACL 中指定的规则进行比较，然后向 Amazon Cognito 返回响应。

## 关于 AWS WAF 网络 ACLs 和亚马逊 Cognito 的注意事项
<a name="user-pool-waf-things-to-know"></a>
+ 您无法配置 Web ACL 规则以匹配用户池请求中的个人身份信息（PII），例如用户名、密码、电话号码或电子邮件地址。此数据将不可用 AWS WAF。应改为配置 Web ACL 规则，使其基于标头、路径和正文中的会话数据进行匹配，例如 IP 地址、浏览器代理和所请求的 API 操作。
+ Web ACL 规则条件仅能在用户**首次**请求用户交互式托管登录页面时返回自定义的阻止响应。当后续连接与自定义阻止响应条件匹配时，虽然会返回您的自定义状态码、标头和重定向设置，但仍显示默认的阻止消息。
+ 被阻止的请求 AWS WAF 不计入任何请求类型的请求速率配额。该 AWS WAF 处理程序在 API 级别的限制处理程序之前被调用。
+ 当您创建 Web ACL 时，Web ACL 要经过一小段时间才能完全传播并可供 Amazon Cognito 使用。传播时间可以从几秒钟到几分钟不等。 AWS WAF [https://docs.aws.amazon.com/waf/latest/APIReference/API_AssociateWebACL.html#API_AssociateWebACL_Errors](https://docs.aws.amazon.com/waf/latest/APIReference/API_AssociateWebACL.html#API_AssociateWebACL_Errors)当您尝试在 Web ACL 完全传播之前将其关联时，将返回。
+ 您可以将一个 Web ACL 与每个用户池相关联。
+ 您的请求可能会导致负载超出 AWS WAF 可以检查的负载限制。请参阅*AWS WAF 开发者指南*中的[超大请求组件处理](https://docs.aws.amazon.com/waf/latest/developerguide/waf-rule-statement-oversize-handling.html)，了解如何配置如何 AWS WAF 处理来自 Amazon Cognito 的超大请求。
+ 您无法将使用[防 AWS WAF 欺诈控制账户盗用 (ATP)](https://docs.aws.amazon.com/waf/latest/developerguide/waf-atp.html) 的网络 ACL 与 Amazon Cognito 用户池相关联。ATP 功能位于 `AWS-AWSManagedRulesATPRuleSet` 托管规则组中。在将您的 Web ACL 与用户池关联之前，请确保它不使用此托管规则组。
+ 当您的 AWS WAF Web ACL 与用户池相关联，并且您的 Web ACL 中的规则显示了验证码时，这可能会导致托管登录 TOTP 注册中出现不可恢复的错误。要创建具有 CAPTCHA 操作且不影响托管登录 TOTP 的规则，请参阅[为托管登录 TOTP MFA 配置您的 AWS WAF 网页 ACL](user-pool-settings-mfa-totp.md#totp-waf)。

AWS WAF 检查对以下端点的请求。

**托管登录和经典托管 UI**  
对 [用户池端点和托管登录参考](cognito-userpools-server-contract-reference.md) 中所有端点的请求。

**公有 API 操作**  
您的应用程序向 Amazon Cognito API 发出的不使用 AWS 凭证进行授权的请求。这包括[InitiateAuth[RespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html)](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)、和 API 操作[GetUser](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_GetUser.html)。范围内的 API 操作 AWS WAF 不需要使用 AWS 凭据进行身份验证。它们未经身份验证，或者是使用会话字符串或访问令牌授权的。有关更多信息，请参阅 [按授权模型分组的 API 操作列表](authentication-flows-public-server-side.md#user-pool-apis-auth-unauth)。

您可以使用以下规则操作在 Web ACL 中配置规则：**计数**、**允许**、**阻止**，或者提供一个 **CAPTCHA** 以响应符合规则的请求。有关更多信息，请参阅 *AWS WAF 开发人员指南* 中的 [AWS WAF 规则](https://docs.aws.amazon.com/waf/latest/developerguide/waf-rules.html)。根据规则操作，您可以自定义 Amazon Cognito 返回给用户的响应。

**重要**  
自定义错误响应的选项取决于您发出 API 请求的方式。  
您可以自定义托管登录请求的错误代码和响应正文。您只能在托管登录中为用户提供 CAPTCHA 以解决此问题。
对于您使用 Amazon Cognito [用户池 API](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/Welcome.html) 提出的请求，可以自定义收到**阻止**响应的请求的响应正文。您也可以指定 400–499 范围内的自定义错误代码。
 AWS Command Line Interface (AWS CLI) 和向生成**区块**或**验证码**响应的请求 AWS SDKs 返回`ForbiddenException`错误。

## 将 Web ACL 与您的用户池相关联
<a name="user-pool-waf-setting-up"></a>

要在您的用户池中使用网络 ACL，您的 AWS Identity and Access Management (IAM) 委托人必须具有以下 Amazon Cognito 和 AWS WAF 权限。有关 AWS WAF 权限的信息，请参阅《*AWS WAF 开发者指南》*中的 [AWS WAF API 权限](https://docs.aws.amazon.com/waf/latest/developerguide/waf-api-permissions-ref.html)。

------
#### [ JSON ]

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Sid": "AllowWebACLUserPool",
			"Effect": "Allow",
			"Action": [
				"cognito-idp:ListResourcesForWebACL",
				"cognito-idp:GetWebACLForResource",
				"cognito-idp:AssociateWebACL"
			],
			"Resource": [
				"arn:aws:cognito-idp:*:123456789012:userpool/*"
			]
		},
		{
			"Sid": "AllowWebACLUserPoolWAFv2",
			"Effect": "Allow",
			"Action": [
				"wafv2:ListResourcesForWebACL",
				"wafv2:AssociateWebACL",
				"wafv2:DisassociateWebACL",
				"wafv2:GetWebACLForResource"
			],
			"Resource": "arn:aws:wafv2:*:123456789012:*/webacl/*/*"
		},
		{
			"Sid": "DisassociateWebACL1",
			"Effect": "Allow",
			"Action": "wafv2:DisassociateWebACL",
			"Resource": "*"
		},
		{
			"Sid": "DisassociateWebACL2",
			"Effect": "Allow",
			"Action": [
				"cognito-idp:DisassociateWebACL"
			],
			"Resource": [
				"arn:aws:cognito-idp:*:123456789012:userpool/*"
			]
		}
	]
}
```

------

尽管您必须授予 IAM 权限，但列出的操作仅用于说明权限，不对应于任何 [API 操作](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/Welcome.html)。

**激活 AWS WAF 您的用户池并关联 Web ACL**

1. 登录 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)。

1. 在导航窗格中，选择 **用户池**，然后选择要编辑的用户池。

1. 在**安全性**部分，选择 **AWS WAF** 选项卡。

1. 选择**编辑**。

1. 选择 “** AWS WAF 与您的用户池一起使用**”。  
![\[选中 “与您的用户池 AWS WAF 一起使用” 的 AWS WAF 对话框的屏幕截图。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/cup-WAF-console.png)

1. 选择您已经创建**的AWS WAF Web ACL**，或者选择在中**创建 Web ACL AWS WAF，在中的**新 AWS WAF 会话中创建一个 Web ACL AWS 管理控制台。

1. 选择**保存更改**。

要以编程方式将 Web ACL 与 AWS Command Line Interface 或 SDK 中的用户池关联，请使用 AWS WAF API [AssociateWeb中的 ACL](https://docs.aws.amazon.com/waf/latest/APIReference/API_AssociateWebACL.html)。Amazon Cognito 没有可关联 Web ACL 的单独 API 操作。

## 测试和记录 AWS WAF 网页 ACLs
<a name="user-pool-waf-evaluating-and-logging"></a>

当您在 Web ACL 中将规则操作设置为 C **ou** nt 时， AWS WAF 会将该请求添加到与该规则匹配的请求计数中。要使用您的用户池测试 Web ACL，请将规则操作设置为**计数**，并考虑与每条规则匹配的请求数量。例如，如果您要设置为**阻止**操作的规则与您确定为正常用户流量的大量请求相匹配，则您可能需要重新配置规则。有关更多信息，请参阅《AWS WAF 开发人员指南》**中的[测试和调整您的 AWS WAF 保护](https://docs.aws.amazon.com/waf/latest/developerguide/web-acl-testing.html)。

您还可以配置 AWS WAF 为将请求标头记录到亚马逊 CloudWatch 日志组、亚马逊简单存储服务 (Amazon S3) 存储桶或亚马逊数据 Firehose。您可以通过 `x-amzn-cognito-client-id` 和 `x-amzn-cognito-operation-name` 识别您使用用户池 API 发出的 Amazon Cognito 请求。托管登录请求仅包含 `x-amzn-cognito-client-id` 标头。有关更多信息，请参阅 *AWS WAF 开发人员指南* 中的[记录 Web ACL 流量](https://docs.aws.amazon.com/waf/latest/developerguide/logging.html)。

AWS WAF web ACLs 在所有用户池[功能计划](cognito-sign-in-feature-plans.md)中都可用。 AWS WAF 的安全功能可作为 Amazon Cognito 威胁防护的补充。您可以在用户池中激活这两项功能。 AWS WAF 对用户池请求的检查单独收费。有关更多信息，请参阅[AWS WAF 定价](https://aws.amazon.com/waf/pricing)。

日志 AWS WAF 请求数据需要按您定位日志的服务收取额外费用。有关更多信息，请参阅 *AWS WAF 开发人员指南* 中的[记录 Web ACL 流量信息的定价](https://docs.aws.amazon.com/waf/latest/developerguide/logging.html#logging-pricing)。

# 用户池区分大小写
<a name="user-pool-case-sensitivity"></a>

默认情况下，您在中创建的 Amazon Cognito 用户池不区分大小写。 AWS 管理控制台 当用户池不区分大小写时，*user@example.com* 和 *User@example.com* 指的是同一个用户。当用户池中的用户名不区分大小写时，`preferred_username` 和 `email` 属性也不区分大小写。

不区分大小写不仅适用于属性输入，也适用于输出。在不区分大小写的用户池中，混合大小写的属性值在用户池的文本输出中会被统一为小写。[用户池文本输出的示例包括用户[信息响应、用户](userinfo-endpoint.md)查询响应（如的输出）以及向 Lambda 触发器的输入事件。[GetUser](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_GetUser.html)](cognito-user-pools-working-with-lambda-triggers.md)

要考虑用户池区分大小写设置，请根据备用用户属性识别应用程序代码中的用户。由于用户名、首选用户名或电子邮件地址属性的大小写在不同的用户配置文件中可能有所不同，因此请改为参阅 `sub` 属性。您还可以在用户池中创建不可变的自定义属性，并为每个新用户配置文件中的属性分配自己的唯一标识符值。首次创建用户时，可以将值写入您创建的不可改变的自定义属性。

**注意**  
无论您的用户池的区分大小写设置如何，Amazon Cognito 都要求来自 SAML 或 OIDC 身份提供商（IdP）的联合用户传递唯一且区分大小写的 `NameId` 或 `sub` 声明。有关唯一标识符区分大小写和 SAML 的更多信息 IdPs，请参阅[实施 SP 发起的 SAML 登录](cognito-user-pools-SAML-session-initiation.md#cognito-user-pools-saml-idp-authentication)。

创建区分大小写的用户池  
如果您使用 AWS Command Line Interface (AWS CLI) 和 API 操作（例如）创建资源 [CreateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html)，则必须将布尔`CaseSensitive`参数设置为`false`。此设置将创建不区分大小写的用户池。如果您不指定值，`CaseSensitive` 默认为 `true`。您在 Amazon Cognito 控制台中创建的用户池不区分大小写。要生成区分大小写的用户池，必须使用 `CreateUserPool` 操作。2020 年 2 月 12 日之前，无论平台如何，用户池都默认区分大小写。  
在 AWS 管理控制台 和`UsernameConfiguration`属性的**登录**菜单中 [DescribeUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UserPoolType.html#CognitoUserPools-Type-UserPoolType-UsernameConfiguration)，您可以查看账户中每个用户池的区分大小写设置。

迁移到新的用户池  
由于用户配置文件之间存在潜在冲突，您无法将 Amazon Cognito 用户池从区分大小写更改为不区分大小写。相反，请将用户迁移到新的用户池。您必须构建迁移代码才能解决与大小写相关的冲突。此代码必须返回唯一的新用户，或者在检测到冲突时拒绝登录尝试。在新的不区分大小写的用户池中，分配一个 [迁移用户 Lambda 触发器](user-pool-lambda-migrate-user.md)。该 AWS Lambda 函数可以在新的不区分大小写的用户池中创建用户。当用户使用不区分大小写的用户池登录失败时，Lambda 函数会从区分大小写的用户池中查找并复制该用户。您还可以针对事件激活迁移用户 Lambda 触发器。[ForgotPassword](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ForgotPassword.html)Amazon Cognito 会将用户信息和事件元数据从登录或密码恢复操作传递到您的 Lambda 函数。当函数在不区分大小写的用户池中创建新用户时，您可以使用事件数据来管理用户名和电子邮件地址之间的冲突。这些冲突是用户名和电子邮件地址之间的冲突，这些名称和地址在区分大小写的用户池中是唯一的，但在不区分大小写的用户池中则相同。  
有关如何在 Amazon Cognito 用户池之间使用迁移用户 Lambda 触发器的更多信息，[请参阅博客中的将用户迁移到 Amazon Cognito](https://aws.amazon.com/blogs/mobile/migrating-users-to-amazon-cognito-user-pools/) 用户池。 AWS 

# 用户池删除保护
<a name="user-pool-settings-deletion-protection"></a>

要使您的管理员不会意外删除用户池，请激活删除保护。启用删除保护后，必须先确认要删除用户池，然后才能将其删除。在中删除用户池时 AWS 管理控制台，可以同时停用删除保护。当您接受停用删除保护的提示并确认要删除时（如下图所示），Amazon Cognito 会删除您的用户池。

![\[的屏幕截图 AWS 管理控制台 显示了删除用户池的提示，并包含了同时停用删除保护的提示。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/amazon-cognito-delete-user-pool-deactivate-deletion-protection.png)


如果您想通过 Amazon Cognito API 请求删除用户池，则必须先在请求`Inactive`中`DeletionProtection`更改为[UpdateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPool.html)。如果您不停用删除保护，Amazon Cognito 会返回 `InvalidParameterException` 错误。停用删除保护后，可以在[DeleteUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_DeleteUserPool.html)请求中删除用户池。

当您在 AWS 管理控制台中创建新的用户池时，Amazon Cognito 默认情况下会激活**删除保护**。当您使用 `CreateUserPool` API 创建用户池时，默认情况下未激活删除保护。要在使用 AWS CLI 或 AWS SDK 创建的用户池中使用此功能，请将`DeletionProtection`参数设置为`True`。

您可以在 Amazon Cognito 控制台的**设置**菜单中的**删除保护**容器中激活或停用删除保护状态。

# 配置删除保护


1. 转到 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)。系统可能会提示您输入 AWS 凭证。

1. 选择**用户池**。

1. 从列表中选择一个现有用户池，或[创建一个用户池](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-as-user-directory.html)。

1. 选择**设置**菜单并导航到**删除保护**选项卡。选择**激活**或**停用**。

1. 在下一个对话框中确认您的选择。

# 管理用户存在错误响应
<a name="cognito-user-pool-managing-errors"></a>

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

使用用户池应用程序客户端的 `PreventUserExistenceErrors` 设置，以启用或禁用用户存在相关错误。当您使用 Amazon Cognito 用户池 API 创建新的应用程序时，默认情况下 `PreventUserExistenceErrors` 为 `LEGACY` 或禁用。在 Amazon Cognito 控制台中，默认选定**防止用户已存在错误**选项（`PreventUserExistenceErrors` 设置为 `ENABLED`）。要更新 `PreventUserExistenceErrors` 配置，请执行以下操作之一：
+ 在 [https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPoolClient.html](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPoolClient.html) API 请求中将 `PreventUserExistenceErrors` 的值更改为 `ENABLED` 和 `LEGACY`。
+ 在 Amazon Cognito 控制台中编辑应用程序客户端，并将**防止用户已存在错误**的状态更改为选定（`ENABLED`）和已取消选择（`LEGACY`）。

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

当此属性的值为 `ENABLED` 时，应用程序客户端不会通过 `UserNotFoundException` 错误来透露您的用户池中不存在某个用户账户。当 `PreventUserExistenceErrors` 配置为 `ENABLED` 时，如果您提交一个不存在的用户名请求，会产生以下效果：
+ Amazon Cognito 会使用非特定信息响应 API 请求，否则其响应可能会泄露存在有效的用户。
+ Amazon Cognito 会向密码重置请求以及使用*除* [基于选择的身份验证](authentication-flows-selection-sdk.md#authentication-flows-selection-choice)（`USER_AUTH`）之外的身份验证流程（例如 `USER_SRP_AUTH` 或 `CUSTOM_AUTH`）的身份验证请求，返回通用的身份验证失败响应。错误响应告知您用户名或密码不正确。
+ 对于基于选择的身份验证请求，Amazon Cognito 会从用户池允许的质询类型中随机选择一种进行响应。您的用户池可能会返回通行密钥、一次性密码或密码质询。
+ Amazon Cognito 账户确认和密码恢复的行为在返回表示代码已发送到模拟传送介质的响应和返回错误之间交 APIs 替进行。`InvalidParameterException`

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

## 身份验证和用户创建操作
<a name="cognito-user-pool-managing-errors-user-auth"></a>

您可以在用户名密码和安全远程密码（SRP）身份验证中配置错误响应。您还可以对使用自定义身份验证返回的错误进行自定义。基于选择的身份验证不受您的 `PreventUserExistenceErrors` 配置的影响。身份验证流程中的用户存在性披露细节

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

**用户名和密码身份验证**  
当 `PreventUserExistenceErrors` 启用时，身份验证流程 `ADMIN_USER_PASSWORD_AUTH`、`USER_PASSWORD_AUTH` 以及 `USER_AUTH` 的 `PASSWORD` 流程会返回 `NotAuthorizedException`，附带 `Incorrect username or password` 消息。当 `PreventUserExistenceErrors` 禁用时，这些流会返回 `UserNotFoundException`。

**基于安全远程密码（SRP）的身份验证**  
作为最佳实践，应仅在没有配置电子邮件地址、电话号码或首选用户名[别名属性](user-pool-settings-attributes.md#user-pool-settings-aliases)的用户池中，对 `USER_SRP_AUTH` 或 `USER_AUTH` 中的 `PASSWORD_SRP` 流程实现 `PreventUserExistenceErrors`。在 SRP 身份验证流程中，具有别名属性的用户可能不会受到用户存在性隐藏的影响。用户名密码身份验证流程（`ADMIN_USER_PASSWORD_AUTH`、`USER_PASSWORD_AUTH` 和 `USER_AUTH` `PASSWORD` 质询）能够完全隐藏来自别名属性的用户存在性信息。  
当有人使用应用程序客户端未知的用户名尝试 SRP 登录时，Amazon Cognito 会在第一步返回一个模拟响应，如 [RFC 5054](https://tools.ietf.org/html/rfc5054#section-2.5.1.3) 所述。Amazon Cognito 始终针对相同的用户名和用户池组合返回相同的盐值以及 [UUID](cognito-terms.md#terms-uuid) 格式的内部用户 ID。当您发送带有密码证明的 `RespondToAuthChallenge` API 时，Amazon Cognito 在用户名或密码不正确时返回一个通用 `NotAuthorizedException` 错误。有关实施 SRP 身份验证的更多信息，请参阅[使用永久密码和安全有效载荷登录](amazon-cognito-user-pools-authentication-flow-methods.md#amazon-cognito-user-pools-authentication-flow-methods-srp)。  
如果您使用基于验证的别名属性，并且不可改变的用户名格式不是 [UUID](cognito-terms.md#terms-uuid)，则可以模拟使用用户名和密码身份验证的通用响应。

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

**身份验证前 Lambda 触发器**  
当用户尝试登录但其用户名未找到时，Amazon Cognito 会调用[身份验证前触发器](user-pool-lambda-pre-authentication.md)。输入事件中包含一个 `UserNotFound` 参数，对于任何不存在的用户，该参数值为 `true`。

以下列表描述了 `PreventUserExistenceErrors` 对用户账户创建的影响。用户创建流程中的用户存在性披露细节

**SignUp**  
当已使用用户名时，`SignUp` 操作始终返回 `UsernameExistsException`。如果在您的应用程序中注册用户时，您不希望 Amazon Cognito 为电子邮件地址和电话号码返回 `UsernameExistsException` 错误，请使用基于验证的别名属性。有关别名的更多信息，请参阅[自定义登录属性](user-pool-settings-attributes.md#user-pool-settings-aliases)。  
有关 Amazon Cognito 如何阻止使用 `SignUp` API 请求来发现用户池中用户的示例，请参阅 [在注册时防止出现电子邮件地址和电话号码的 `UsernameExistsException` 错误](#cognito-user-pool-managing-errors-prevent-userexistence-errors)。

**导入的用户**  
如果 `PreventUserExistenceErrors` 已启用，则在对导入的用户进行身份验证期间，将返回通用 `NotAuthorizedException` 错误，指示用户名或密码不正确，而不是返回 `PasswordResetRequiredException`。请参阅[要求导入的用户重置密码](cognito-user-pools-using-import-tool.md#cognito-user-pools-using-import-tool-password-reset)了解更多信息。

**迁移用户 Lambda 触发器**  
当 Lambda 触发器在原始事件上下文中设置了空响应时，Amazon Cognito 将为不存在的用户返回模拟响应。有关更多信息，请参阅 [利用用户迁移 Lambda 触发器导入用户](cognito-user-pools-import-using-lambda.md)。

### 在注册时防止出现电子邮件地址和电话号码的 `UsernameExistsException` 错误
<a name="cognito-user-pool-managing-errors-prevent-userexistence-errors"></a>

以下示例演示了在用户池中配置别名属性时，如何在对 `SignUp` API 请求的响应中，防止重复的电子邮件地址和电话号码生成 `UsernameExistsException` 错误。您必须在创建用户池时使用电子邮件地址或电话号码作为别名属性。有关更多信息，请参阅[用户池属性](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-attributes.html#user-pool-settings-aliases)的*自定义登录属性* 部分。

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

   ** 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"
       }
   }
   ```

1. Jie 提供了发送过来的代码，确认其拥有该电子邮件地址。这样就完成了用户注册。

   ** AWS CLI 命令示例**

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

1. Shirley 注册了一个新的用户账户并提供了电子邮件地址 `jie@example.com`。Amazon Cognito 不会返回 `UsernameExistsException` 错误，而是向 Jie 的电子邮件地址发送确认码。

   ** 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"
       }
   }
   ```

1. 在另一种情况下，Shirley 拥有对 `jie@example.com` 的所有权。Shirley 收到了 Amazon Cognito 发送到 Jie 电子邮件地址的代码，并尝试确认该账户。

   ** 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 必须证明对该电子邮件地址的所有权。在具有别名属性的用户池中，此行为会阻止使用公共 `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
```

## 密码重置操作
<a name="cognito-user-pool-managing-errors-password-reset"></a>

当您防止出现用户存在错误时，Amazon Cognito 会对用户密码重置操作返回以下响应。

**ForgotPassword**  
当找不到用户、用户已停用或没有经过验证的传送机制来恢复其密码时，Amazon Cognito 会为用户返回 `CodeDeliveryDetails` 以及模拟的传递媒介。模拟的传递媒介由用户池的输入用户名格式和验证设置决定。

**ConfirmForgotPassword**  
Amazon Cognito 为不存在或已禁用的用户返回 `CodeMismatchException` 错误。如果在使用 `ForgotPassword` 时不请求代码，Amazon Cognito 将返回 `ExpiredCodeException` 错误。

## 确认操作
<a name="cognito-user-pool-managing-errors-confirmation"></a>

当您防止出现用户存在错误时，Amazon Cognito 会对用户确认和验证操作返回以下响应。

**ResendConfirmationCode**  
Amazon Cognito 为已禁用或不存在的用户返回 `CodeDeliveryDetails`。Amazon Cognito 会向现有用户的电子邮件或电话发送确认码。

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