

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

# Amazon Cognito 故障排除
<a name="troubleshooting"></a>

本章提供您在使用 Amazon Cognito 时可能遇到的常见问题的解决方案。Amazon Cognito 的实施可能会面临身份验证流程、用户池配置和身份联合验证设置方面的各种挑战。无论您是在开发新应用程序还是维护现有应用程序，本故障排除指南都将帮助您快速发现和解决常见问题。

## 自定义域配置错误
<a name="troubleshoot_custom_domain_errors"></a>

在 Amazon Cognito 中配置自定义域名时，您可能会收到错误消息。常见错误包括验证问题、证书问题或域冲突。

### `Custom domain is not a valid subdomain`
<a name="troubleshoot_custom_domain_subdomain"></a>

此错误表示父域的 DNS 解析存在问题。Amazon Cognito 不支持顶级域，要求父域具有 DNS A 记录用于验证。

**问题**  
此错误表示父域的 DNS 解析存在问题。Amazon Cognito 不支持顶级域，要求父域具有 DNS A 记录用于验证。

**解决方案**  
+ **为父域创建 A 记录：**您必须在 DNS 配置中为自定义域的父域创建 A 记录。
  + **示例：**如果您的自定义域是 `auth.xyz.yourdomain.com`，则父域是 `xyz.yourdomain.com`。如果您要将 `xyz.yourdomain.com` 配置为自定义域，则父域为 `yourdomain.com`。
  + 父域必须解析为有效的 IP 地址。如果它未指向真实的 IP 地址，则可以使用虚拟 IP 地址，例如 `8.8.8.8`。
+ **验证 DNS 传播（可选但推荐）：**要确保您的 DNS 提供商已传播更改，您可以运行 `dig` 命令。
  + 如果使用 `auth.xyz.yourdomain.com` 作为自定义域：`dig A xyz.yourdomain.com +short`
  + 如果使用 `xyz.yourdomain.com` 作为自定义域：`dig A yourdomain.com +short`
  + 该命令应返回您配置的 IP 地址。如果没有，请等到更改已完全传播。
+ **删除父域 A 记录：**在 Amazon Cognito 中成功创建自定义域后，如果父域为虚拟域，则可以删除您为父域创建的 A 记录。

有关更多信息，请参阅[将您自己的域用于托管 UI](cognito-user-pools-add-custom-domain.md)。

### `Domain already associated with another user pool`
<a name="troubleshoot_domain_already_associated"></a>

自定义域名在所有 AWS 账户 和区域中必须是唯一的。

**问题**  
自定义域名在所有 AWS 账户 和区域中必须是唯一的。

**解决方案**  
+ 要为新用户池使用该域名，必须从当前与其关联的用户池中删除自定义域。
+ **删除后等待：**自定义域需要一段时间才能从第一个用户池中完全删除。删除后立即使用相同的名称创建新自定义域仍可能导致此错误。请等待几分钟，然后重试。

### `One or more of the CNAMEs that you provided are already associated with a different resource`
<a name="troubleshoot_cname_already_associated"></a>

当您创建自定义域名时，Amazon Cognito 会创建一个 AWS由亚马逊 CloudFront 托管的分配。一个域名只能用于一个 Amazon CloudFront 分配。如果该域名已被用作另一个 Amazon CloudFront 分销的备用域名，则会发生此错误。

**问题**  
当您创建自定义域名时，Amazon Cognito 会创建一个 AWS由亚马逊 CloudFront托管的分配。一个域名只能用于一个 Amazon CloudFront 分配。如果该域名已被用作另一个 Amazon CloudFront 分销的备用域名，则会发生此错误。

**解决方案**  
+ **选项 1：**为您的 Amazon Cognito 自定义域使用不同的域名。
+ **选项 2：**如果您使用 Amazon Cognito 的域名，请不要将其用于其他亚马逊 CloudFront 发行版。

### `The specified SSL certificate doesn't exist`
<a name="troubleshoot_ssl_certificate_not_exist"></a>

Amazon Cognito 使用亚马逊 CloudFront，无论用户池位于哪个区域，都要求 AWS Certificate Manager `us-east-1` (ACM) AWS 区域证书必须位于（弗吉尼亚北部）。

**问题**  
Amazon Cognito 使用亚马逊 CloudFront，无论用户池位于哪个区域，都要求 AWS Certificate Manager `us-east-1` (ACM) AWS 区域证书必须位于（弗吉尼亚北部）。

**解决方案**  
+ **确保证书区域：**确认 ACM 证书位于 `us-east-1` 区域。
+ **检查证书有效性：**确保所选证书未过期。
+ **导入的证书：**如果您已将证书导入 ACM，请确保：
  + 它由公有证书颁发机构颁发。
  + 它包括正确的证书链。
+ **AWS KMS 策略检查：** AWS Key Management Service (AWS KMS) 策略中针对创建域的 IAM 用户或角色的明确`deny`声明可能会导致此错误。具体而言，请在 `kms:DescribeKey`、`kms:CreateGrant` 或 `kms:*` 操作中检查是否存在显式拒绝。

## `Invalid refresh token`错误
<a name="troubleshoot_invalid_refresh_token"></a>

**问题**  
当您尝试通过 `AdminInitiateAuth` 或 `InitiateAuth` API 操作使用刷新令牌从 Amazon Cognito 用户池中获取新的访问和 ID 令牌时，您会收到 `Invalid refresh token` 错误消息。

**解决方案**  
根据您的用户池配置和 API 使用情况实施以下故障排除步骤：  
+ **确保应用程序客户端 ID 一致：**调用 `AdminInitiateAuth` 或 `InitiateAuth` API 进行令牌刷新时，使用的必须与生成刷新令牌的初始身份验证期间使用的应用程序客户端 ID 完全相同。
+ **确认设备：如果您在**用户池中启用了[设备跟踪](amazon-cognito-user-pools-device-tracking.md)，但用户的设备尚未得到确认，则必须先调用 [ConfirmDevice](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ConfirmDevice.html)API。在用户确认其设备后，您便可以交换刷新令牌。
+ **在刷新请求中包含设备密钥：**如果已启用设备跟踪，请在使用 `REFRESH_TOKEN_AUTH` 流程时包含唯一的设备密钥作为 `AuthParameter`：

  ```
  {
    "AuthFlow": "REFRESH_TOKEN_AUTH",
    "AuthParameters": {
      "REFRESH_TOKEN": "example_refresh_token",
      "SECRET_HASH": "example_secret_hash", // Required if your app client uses a client secret
      "DEVICE_KEY": "example_device_key" 
    }
  }
  ```
+ **使用 `USER_SRP_AUTH` 进行设备跟踪：**如果您使用设备跟踪，则初始身份验证流程必须是 `USER_SRP_AUTH`。

有关更多信息，请参阅 [使用用户池中的用户设备](amazon-cognito-user-pools-device-tracking.md)。

## 联合身份验证中的无效 SAML 响应错误
<a name="troubleshoot_invalid_saml_response"></a>

用户会在尝试使用 SAML 2.0 联合到 Amazon Cognito 时收到各种 `Invalid SAML response` 和类似错误。可能会由于属性映射问题、证书问题或配置不匹配而发生这些错误。

### `Invalid user attributes: Required attribute`
<a name="troubleshoot_saml_required_attribute"></a>

**问题**  
用户缺少用户池中所需属性的值，或者 IdP 正在尝试删除或更新不可变的属性。

**解决方案**  
+ 检查用户池配置中定义的[必需属性](user-pool-settings-attributes.md#how-to-edit-standard-attributes)。
+ 使用浏览器中的网络捕获工具检索 SAML 响应。您可能需要执行 URL 和 base64 解码。请验证该属性是否存在于 SAML 断言中。
+ 登录您的身份提供者并查看它发送给 Amazon Cognito 的属性。请验证 IdP 是否配置为使用正确的名称发送必需属性。
+ 对于不可变的属性，请运行以下 AWS CLI 命令来识别它们：。`aws cognito-idp describe-user-pool --user-pool-id USER-POOL-ID --query 'UserPool.SchemaAttributes[?Mutable==`false`].Name'`
+ 在您的 IdP 的 SAML 属性映射中，删除所有以不可变 Amazon Cognito 属性为目标的映射。或者，将目标属性更新为不同的可变属性。

### `Invalid SAML response received: SAML Response signature is invalid`
<a name="troubleshoot_saml_signature_invalid"></a>

**问题**  
您的 IdP 已更新其 SAML 签名证书，导致 SAML 响应中的证书与存储在 Amazon Cognito 中的元数据文件不匹配。

**解决方案**  

1. 从您的 IdP 下载最新的元数据文件。

1. 在 Amazon Cognito 控制台中，导航到用户池的**社交和外部提供商**，编辑您的 SAML 提供商，然后将现有元数据文件替换为新下载的文件。

### `Audience restriction` 或 `Application with identifier not found`
<a name="troubleshoot_saml_audience_restriction"></a>

**问题**  
在您的 IdP 中配置了错误的实体 ID，或者断言使用了其他用户池的统一资源名称（URN）。

**解决方案**  

1. 从控制台的**概述**部分获取您的 Amazon Cognito 用户池 ID。

1. 在您的 IdP 的管理控制台中，更新用户池的 SAML 应用程序中的实体 ID。请将实体 ID 配置为匹配格式 `urn:amazon:cognito:sp:USER_POOL_ID`。将 `USER_POOL_ID` 替换为上一步中的用户池 ID。

### `An error was encountered with the requested page`
<a name="troubleshoot_saml_acs_url"></a>

**问题**  
向您的 IdP 注册的断言使用者服务（ACS）URL 配置不正确，或者 IdP 未使用所需的 POST 绑定发送 SAML 响应。

**解决方案**  
+ 在 IdP 的管理控制台中，使用正确的 ACS URL 格式更新应用程序，确保其使用 `HTTP POST` 绑定。
+ **默认域格式：**`https://cognito-idp.Region.amazonaws.com/your user pool ID/saml2/idpresponse`
+ **自定义域格式：**`https://auth.example.com/saml2/idpresponse`

### `Invalid relayState from identity provider`
<a name="troubleshoot_saml_relay_state"></a>

**问题**  
`RelayState` 参数缺失或无效，或者 IdP 和 Amazon Cognito 之间的 URL 不匹配。

**解决方案**  
+ **对于[服务提供商启动（SP 启动）](cognito-user-pools-SAML-session-initiation.md#cognito-user-pools-saml-idp-authentication)的流程：**请始终在您的用户池 `/oauth2/authorize` 端点上启动身份验证。在用户初始访问 Amazon Cognito 时未返回 `RelayState` 参数的 SAML 断言不是 SP 启动的有效请求。
+ **对于[身份提供者启动（IdP 启动）](cognito-user-pools-SAML-session-initiation.md#cognito-user-pools-SAML-session-initiation-idp-initiation)的流程：**IdP 必须使用所需格式，在对 `/saml2/idpresponse` 端点的 SAML 断言中包含 `RelayState` 参数：`redirect_uri=REDIRECT_URI&state=STATE`。

有关更多信息，请参阅 [将 SAML 身份提供者与用户池配合使用](cognito-user-pools-saml-idp.md)。

## 托管登录用户无法选择 MFA 因素
<a name="troubleshoot_mfa_factor_selection"></a>

**问题**  
用户在通过托管登录进行登录时无法选择其首选 MFA 方法，或者系统不会提示他们选择您期望的 MFA 方法。

**解决方案**  
Amazon Cognito 遵循特定的逻辑，根据用户池设置、用户属性和账户恢复配置来确定用户可以使用哪些 MFA 因素。例如，如果将电子邮件配置为其主要账户恢复方法，则用户无法使用电子邮件 MFA。  
要覆盖默认 MFA 因素选择，您可以实施以下任一方法：  
+ 对于公共应用程序：[SetUserMFAPreference](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_SetUserMFAPreference.html)使用有效的访问令牌允许用户设置自己的 MFA 首选项
+ 对于管理员管理的应用程序：使用[AdminSetUserMFAPreference](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminSetUserMFAPreference.html) AWS 凭据配置用户 MFA 首选项
这两个操作都允许您为个人用户启用或禁用短信、电子邮件和 TOTP MFA 方法，并将一种方法设置为首选。

有关更多信息，请参阅 [向用户池添加 MFA](user-pool-settings-mfa.md)。

### 无密码和通行密钥用户无法使用 MFA
<a name="troubleshoot_passwordless_mfa"></a>

**问题**  
使用一次性密码 (OTP) 身份验证方法登录的用户不能添加或使用多重身份验证。

**解决方案**  
OTP 登录流程不支持 MFA。但是，带有用户验证的密钥身份验证可以满足 MFA 要求。`MULTI_FACTOR_WITH_USER_VERIFICATION`在您的用户池中设置为 `FactorConfiguration``WebAuthnConfiguration`，以允许密钥计为多因素身份验证。

有关更多信息，请参阅[用户池身份验证](getting-started-identity-pools-application.md#user-pool-authentication)。

## 无法通过电子邮件/短信接收密码重置验证码
<a name="troubleshoot_password_reset_delivery"></a>

**问题**  
在忘记密码工作流程中，用户无法通过电子邮件或短信接收验证码。

**解决方案**  
无法接收验证码的原因有很多。请按以下核对清单来排查问题：  
+ 检查用户的垃圾邮件文件夹。
+ 确认用户存在于用户池中。
+ 验证用户的状态是否不是 `FORCE_CHANGE_PASSWORD`。在这种情况下，用户由管理员创建，当他们使用临时密码登录时，Amazon Cognito 会提示他们设置密码。
+ 检查用户是否具有经过验证的电子邮件或电话号码属性。
+ 检查您的短信收发账户支出限额
+ 检查您的 Amazon Simple Email Service（Amazon SES）消息发送配额。
+ 检查短信和 Amazon SES（如果您的用户池配置为**使用 Amazon SES 发送电子邮件**）是否都已移出沙盒。如果他们未从沙箱中移出，则电子邮件地址或电话号码未经Amazon SES验证或 AWS End User Messaging SMS 将无法接收密码重置码。
+ 如果用户有处于活动状态的 MFA 因素，请检查它们是否没有尝试向同一因素生成消息。例如，电子邮件 MFA 处于活动状态的用户无法通过电子邮件发送密码重置代码。

有关更多信息，请参阅[Amazon Cognito 用户池的电子邮件设置](user-pool-email.md)和[Amazon Cognito 用户池的短信设置](user-pool-sms-settings.md)。

## 密码重置失败，恢复属性未验证：`Could not reset password for the account, please contact support or try again`
<a name="troubleshoot_password_reset_unverified_recovery"></a>

**问题**  
由于未验证的恢复方法或 MFA 配置冲突，用户在尝试重置密码时会收到此错误。当用户的电子邮件或电话号码属性未验证时，或者他们的 MFA 设置阻止使用配置的恢复方法时，就会发生错误。

**解决方案**  
查看您的用户池的账户恢复配置和受影响用户的验证状态：  
+ **验证恢复设置：**在您的用户池中，导航至 “**登录**” > “**用户帐户恢复**”。确保启用了**自助服务帐户恢复**，并查看您的**恢复邮件传送方式**设置。
+ **检查用户属性验证：**验证用户是否拥有与您的恢复方法配置相匹配的经过验证的电子邮件地址或电话号码。在控制台中，转到用户的个人资料，选择**用户属性** > **编辑**，然后将相应的属性标记为已验证。
+ **解决 MFA 冲突：首选** MFA 方法为电子邮件的用户无法通过电子邮件接收密码重置代码，使用 SMS MFA 的用户也无法通过短信接收密码。更新您的**恢复消息传送方式**以提供其他选项，例如**短信（如果有），否则使用电子邮件或电子邮件****（如果有），否则提供短信**。
+ **管理验证：**当无法访问控制台时，使用 API 操作[AdminUpdateUserAttributes](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminUpdateUserAttributes.html)以编程方式验证用户属性。

有关更多信息，请参阅 [密码、账户恢复和密码策略](managing-users-passwords.md)。

## `SECRET_HASH` 错误
<a name="troubleshoot_secret_hash_required"></a>

**问题**  
向具有客户端密钥的应用程序客户端发出的身份验证 API 请求返回错误，例如 `An error occurred (NotAuthorizedException) when calling the ForgotPassword operation: Client 1example23456789 is configured with secret but SECRET_HASH was not received.`

**解决方案**  
您的应用程序必须计算当前用户、应用程序客户端和客户端密钥的 `SECRET_HASH`。计算方法是：  

```
Base64 ( HMAC_SHA256 ( "client secret", "Username" + "Client Id" ) )
```
要获取客户端密钥，您可以：  

1. 打开 Amazon Cognito 控制台，然后从**应用程序客户端**菜单导航到您的应用程序客户端。在**应用程序客户端信息**部分，找到**客户端密钥**。选择**显示客户端密钥**，此时将显示您的应用程序客户端密钥。

1. 生成[DescribeUserPoolClient](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_DescribeUserPoolClient.html)请求。客户端密钥包含在响应中。

有关更多信息，请参阅 [计算密钥哈希值](signing-up-users-in-your-app.md#cognito-user-pools-computing-secret-hash)。

## Amazon Cognito 控制台为新用户池选择默认配置
<a name="troubleshoot_console_default_config"></a>

**问题**  
当您在控制台中设置新用户池时，Amazon Cognito 为您选择多个默认设置。创建用户池后，一些设置无法更改。如何做出明智的选择并了解 Amazon Cognito 自动选择了什么？

**解决方案**  
Amazon Cognito 控制台中的新用户池设置专为快速测试和原型设计而设计。控制台仅为您提供最关键的配置选项，即创建用户池后无法更改的配置选项。Amazon Cognito 自动配置的所有其他设置都可以在稍后修改。  
建议采取以下方法：  

1. 在完善实施时使用控制台创建测试用户池。

1. 确定生产配置后，将这些设置应用于测试用户池。

1. 使用[DescribeUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_DescribeUserPool.html)和 [DescribeUserPoolClient](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_DescribeUserPoolClient.html)API 操作生成经过测试的配置的 JSON 模板。

1. 将这些模板与 CDK AWS SDKs、REST API 等部署工具结合使用，或者 CloudFormation 创建您的生产资源。

有关更多信息，请参阅 [用户池入门](getting-started-user-pools.md)。

## 其他故障排除资源
<a name="troubleshoot_additional_resources"></a>

如需其他故障排除指南和社区提供的解决方案，您还可以探索以下外部资源：
+ [AWS re: post Amazon Cognito](https://repost.aws/tags/TAkhAE7QaGSoKZwd6utGhGDA/amazon-cognito) 社区——浏览社区问题和解决方案
+ [AWS 知识中心 Amazon Cognito 文章——精选疑难解答文章](https://aws.amazon.com/premiumsupport/knowledge-center/cognito/)