

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

# 将 IdP 属性映射到配置文件和令牌
<a name="cognito-user-pools-specifying-attribute-mapping"></a>

身份提供者（IdP）服务（包括 Amazon Cognito）通常可以记录有关用户的更多信息。您可能想知道他们在哪家公司工作、如何联系他们以及其他可供识别的信息。但是，这些属性的格式在不同的提供者之间存在差异。例如，使用您的用户池设置 IdPs 来自三个不同供应商的三个供应商，并检查每个供应商的 SAML 断言、ID 令牌或`userInfo`负载示例。其中一个 IdP 将用户的电子邮件地址表示为 `email`，另一个表示为 `emailaddress`，第三个表示为 `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress`。

 IdPs 与用户池整合带来的一个主要好处是，能够将各种属性名称映射到具有一致、可预测的共享属性名称的单个 OIDC 令牌架构中。这样，您的开发人员就无需维护处理各种复杂单点登录事件的逻辑。这种格式整合就是属性映射。用户池属性映射将 IdP 属性名称分配给相应的用户池属性名称。例如，您可以将用户池配置为将 `emailaddress` 声明的值写入标准用户池属性 `email`。

每个用户池 IdP 都有单独的属性映射架构。要为您的 IdP 指定属性映射，请在 Amazon Cognito 控制台、 AWS SDK 或用户池 REST API 中配置用户池身份提供者。

## 有关映射的需知信息
<a name="cognito-user-pools-specifying-attribute-mapping-requirements"></a>

在开始设置用户属性映射之前，请查看以下重要详细信息。
+ 当联合用户登录到您的应用程序时，您的用户池需要的每个用户池属性都必须存在一个映射。例如，如果您的用户池需要 `email` 属性来进行注册，则将此属性映射到 IdP 中的对等属性。
+ 默认情况下，映射的电子邮件地址未经验证。您无法使用一次性代码验证映射的电子邮件地址。而是要映射 IdP 的属性来获取验证状态。例如，Google 和大多数 OIDC 提供商都包含 `email_verified` 属性。
+ 您可以将身份提供者（IdP）令牌映射到用户池中的自定义属性。社交提供者提供访问令牌，而 OIDC 提供者提供访问令牌和 ID 令牌。要映射令牌，请添加一个最大长度为 2048 个字符的自定义属性，向您的应用程序客户端授予对该属性的写入权限，然后将 `access_token` 或 `id_token` 从 IdP 映射到自定义属性。
+ 对于每个映射的用户池属性，最大值长度 2048 个字符必须足够大，才能容纳 Amazon Cognito 从 IdP 处获取的值。否则，当用户登录到您的应用程序时，Amazon Cognito 会报告错误。当令牌长度超过 2048 个字符时，Amazon Cognito 不支持将 IdP 令牌映射到自定义属性。
+ Amazon Cognito 从联合身份验证 IdP 传递的特定声明中派生出联合用户配置文件中的 `username` 属性，如下表所示。Amazon Cognito 在此属性值前面加上 IdP 的名称，例如 `MyOIDCIdP_[sub]`。当您希望联合用户拥有与外部用户目录中的属性完全匹配的属性时，请将该属性映射到 Amazon Cognito 登录属性，如 `preferred_username`。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/cognito-user-pools-specifying-attribute-mapping.html)
+ 当用户池[不区分大小写](user-pool-case-sensitivity.md)时，Amazon Cognito 会将联合用户自动生成的用户名中的用户名源属性转换为小写字母。以下是区分大小写的用户池的示例用户名：`MySAML_TestUser@example.com`。以下是*不区分大小写*的用户池的相同用户名：`MySAML_testuser@example.com`。

  在不区分大小写的用户池中，处理用户名的 Lambda 触发器必须考虑到对任何混合大小写的声明进行的这种修改，以适应用户名称源属性。要将您的 IdP 链接到区分大小写设置与当前用户池不同的用户池，请创建一个新的用户池。
+ 当用户登录您的应用程序时，Amazon Cognito 必须能够更新映射的用户池属性。用户通过某个 IdP 登录时，Amazon Cognito 将使用来自该 IdP 的最新信息更新映射的属性。Amazon Cognito 仅在映射的属性的值发生变化时才对其进行更新。要确保 Amazon Cognito 可以更新属性，请检查以下要求：
  + 您从 IdP 映射的所有用户池自定义属性都必须为*可变的*。您可以随时更新可变的自定义属性。相比之下，只有在首次创建用户配置文件时，才能为用户的*不可变* 自定义属性设置值。要在 Amazon Cognito 控制台中创建可变的自定义属性，请在**注册**菜单中选择**添加自定义属性**时，为您添加的属性激活**可变**复选框。或者，如果您使用 [CreateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html)API 操作创建用户池，则可以将每个属性的`Mutable`参数设置为`true`。如果您的 IdP 为映射的不可变属性发送一个值，Amazon Cognito 会返回错误且登录失败。
  + 在应用程序的应用程序客户端设置中，映射的属性必须*可写*。您可以在 Amazon Cognito 控制台的 **App clients (应用程序客户端)** 页面中设置哪些属性为可写属性。或者，如果您使用 [https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPoolClient.html](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPoolClient.html) API 操作创建应用程序客户端，则可以将这些属性添加到 `WriteAttributes` 数组。如果您的 IdP 为映射的不可写属性发送一个值，Amazon Cognito 不会设置该属性值，而是继续进行身份验证。
+ 当 IdP 属性包含多个值时，Amazon Cognito 会将所有值扁平化为一个以逗号分隔的字符串，并用方括号字符 `[` 和 `]` 将其括起来。Amazon Cognito 对包含除 `.`、`-`、`*` 和 `_` 之外的非字母数字字符的值进行 URL 格式编码。在您的应用程序中使用这些值之前，您必须解码并解析各个值。
+ 目标属性会保留属性映射规则分配给它的任何值，除非登录或管理操作对其进行了更改。当不再在提供者令牌或 SAML 断言中发送源属性时，Amazon Cognito 不会从用户处移除属性。以下操作会从联合用户的用户池配置文件中移除属性的值：

  1. IdP 为源属性发送空值，并且映射规则将该空值应用于目标属性。

  1. 您可以使用[DeleteUserAttributes](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_DeleteUserAttributes.html)或[AdminDeleteUserAttributes](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminDeleteUserAttributes.html)请求清除映射属性的值。

## 指定适用于用户池的身份提供者属性映射（AWS 管理控制台）
<a name="cognito-user-pools-specifying-attribute-mapping-console"></a>

您可以使用为您的用户 AWS 管理控制台 池的 IdP 指定属性映射。

**注意**  
只有当陈述存在于传入令牌中时，Amazon Cognito 才会将传入陈述映射到用户池属性。如果之前映射的声明不再存在于传入令牌中，则不会被删除或更改。如果您的应用程序需要映射已删除的声明，则可以使用预身份验证 Lambda 触发器在身份验证期间删除自定义属性，并允许从传入令牌重新填充这些属性。

**指定社交 IdP 属性映射**

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

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

1. 选择**社交和外部提供商**菜单。

1. 选择**添加身份提供者**，或者选择您已配置的 **Facebook**、**Google**、**Amazon** 或 **Apple** IdP。找到 **Attribute mapping**（属性映射），然后选择 **Edit**（编辑）。

   有关添加社交 IdP 的更多信息，请参阅[将社交身份提供者与用户池配合使用](cognito-user-pools-social-idp.md)。

1. 对于需要映射的每个属性，请完成以下步骤：

   1. 从 **User pool attribute**（用户池属性）列中选择属性。这是分配给您的用户池中用户配置文件的属性。自定义属性在标准属性之后列出。

   1. 从属性列中选择一个***<provider>*属性**。这将是从提供商目录传递的属性。在下拉列表中提供来自社交服务提供商的已知属性。

   1. 要在 IdP 和 Amazon Cognito 之间映射其它属性，请选择 **Add another attribute**（添加其它属性）。

1. 选择 **Save changes**（保存更改）。

**指定 SAML 提供商属性映射**

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

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

1. 选择**社交和外部提供商**菜单。

1. 选择 **Add an identity provider**（添加身份提供者），或者选择您已配置的 SAML IdP。找到 **Attribute mapping**（属性映射），然后选择 **Edit**（编辑）。有关添加 SAML IdP 的更多信息，请参阅[将 SAML 身份提供者与用户池配合使用](cognito-user-pools-saml-idp.md)。

1. 对于需要映射的每个属性，请完成以下步骤：

   1. 从 **User pool attribute**（用户池属性）列中选择属性。这是分配给您的用户池中用户配置文件的属性。自定义属性在标准属性之后列出。

   1. 从 **SAML attribute**（SAML 属性）列中选择属性。这将是从提供商目录传递的属性。

      您的 IdP 可能会提供示例 SAML 断言以供参考。有些 IdPs 使用简单的名称，例如`email`，而另一些则使用类似于 URL 格式的属性名称：

      ```
      http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
      ```

   1. 要在 IdP 和 Amazon Cognito 之间映射其它属性，请选择 **Add another attribute**（添加其它属性）。

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

## 为您的用户池（AWS CLI 和 AWS API）指定身份提供商属性映射
<a name="cognito-user-pools-specifying-attribute-mapping-cli-api"></a>

以下请求正文按顺序将 SAML 提供商 “MyIdP” 属性`emailaddress``birthdate`、、和[UpdateIdentityProvider](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateIdentityProvider.html)映射`phone`到用户池属性`email``birthdate``phone_number`、和。[CreateIdentityProvider](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateIdentityProvider.html)这是 SAML 2.0 提供者的完整请求正文，您的请求正文将因 IdP 类型和具体细节而有所不同。属性映射位于 `AttributeMapping` 参数中。

```
{
   "AttributeMapping": { 
      "email" : "emailaddress",
      "birthdate" : "birthdate",
      "phone_number" : "phone"
   },
   "IdpIdentifiers": [ 
      "IdP1",
      "pdxsaml"
   ],
   "ProviderDetails": { 
      "IDPInit": "true", 
      "IDPSignout": "true", 
      "EncryptedResponses" : "true", 
      "MetadataURL": "https://auth.example.com/sso/saml/metadata", 
      "RequestSigningAlgorithm": "rsa-sha256"
   },
   "ProviderName": "MyIdP",
   "ProviderType": "SAML",
   "UserPoolId": "us-west-2_EXAMPLE"
}
```

使用以下命令为您的用户池指定 IdP 属性映射。

**在提供商创建时指定属性映射**
+ AWS CLI: `aws cognito-idp create-identity-provider`

  带元数据文件的示例：`aws cognito-idp create-identity-provider --user-pool-id <user_pool_id> --provider-name=SAML_provider_1 --provider-type SAML --provider-details file:///details.json --attribute-mapping email=http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress`

  其中 `details.json` 包含：

  ```
  { 
      "MetadataFile": "<SAML metadata XML>"
  }
  ```
**注意**  
如果*<SAML metadata XML>*包含任何引号 (`"`)，则必须对其进行转义 (`\"`)。

  带元数据 URL 的示例：

  ```
  aws cognito-idp create-identity-provider \
  --user-pool-id us-east-1_EXAMPLE \
  --provider-name=SAML_provider_1 \
  --provider-type SAML \
  --provider-details MetadataURL=https://myidp.example.com/saml/metadata \
  --attribute-mapping email=http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
  ```
+ API/SDK：[CreateIdentityProvider](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateIdentityProvider.html)

**指定现有 IdP 的属性映射**
+ AWS CLI: `aws cognito-idp update-identity-provider`

  示例：`aws cognito-idp update-identity-provider --user-pool-id <user_pool_id> --provider-name <provider_name> --attribute-mapping email=http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress`
+ API/SDK：[UpdateIdentityProvider](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateIdentityProvider.html)

**获取有关特定 IdP 的属性映射的信息**
+ AWS CLI: `aws cognito-idp describe-identity-provider`

  示例：`aws cognito-idp describe-identity-provider --user-pool-id <user_pool_id> --provider-name <provider_name>`
+ API/SDK：[DescribeIdentityProvider](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_DescribeIdentityProvider.html)