

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

# Amazon Cognito 身份池
<a name="cognito-identity"></a>

Amazon Cognito 身份池是联合身份的目录，您可以用它交换 AWS 凭证。身份池会为您的应用程序的用户生成临时 AWS 证书，无论他们已登录还是您尚未识别他们的身份。通过 AWS Identity and Access Management (IAM) 角色和策略，您可以选择要向用户授予的权限级别。用户能够以访客身份开始，然后检索您保留在 AWS 服务中的资产。然后，他们可以通过第三方身份提供者登录，以解锁对您提供给注册会员的资产的访问权限。第三方身份提供商可以是 Apple 或 Google 等消费者（社交） OAuth 2.0 提供商、自定义 SAML 或 OIDC 身份提供商，也可以是您自己设计的自定义身份验证方案（也称为*开发者提供商*）。Amazon Cognito 身份池的功能

**签署请求 AWS 服务**  
将 [API 请求签名](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html)给亚马逊简单存储服务 (Amazon S3) Servic AWS 服务 e 和亚马逊 DynamoDB。使用亚马逊 Pinpoint 和亚马逊等服务分析用户活动。 CloudWatch

**使用基于资源的策略筛选请求**  
对于用户对资源的访问权限进行精细控制。将用户声明转换为 [IAM 会话标签](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)，并构建 IAM policy 以向用户的不同子集授予资源访问权限。

**分配访客访问权限**  
对于尚未登录的用户，请将您的身份池配置为生成具有较窄访问权限范围的 AWS 凭证。通过单点登录提供者对用户进行身份验证以提升其访问权限。

**根据用户特征分配 IAM 角色**  
为所有经身份验证的用户分配一个 IAM 角色，或者根据每个用户的声明选择角色。

**接受各种身份提供者**  
将 ID 或访问令牌、用户池令牌、SAML 断言或社交提供者 OAuth 令牌交换凭证。 AWS 

**验证您自己的身份**  
执行您自己的用户验证，并使用您的开发者 AWS 证书为您的用户颁发证书。

您可能已经有一个 Amazon Cognito 用户池，用于为您的应用程序提供身份验证和授权服务。您可以将用户池设置为身份池的身份提供者（IdP）。当你这样做时，你的用户可以通过你的用户池进行身份验证 IdPs，将他们的声明整合到一个普通的 OIDC 身份令牌中，然后用该令牌兑换证书。 AWS 然后，您的用户可以在签名的请求中向 AWS 服务提供其凭证。

还可以将来自任何身份提供者的经身份验证的声明直接提供给身份池。Amazon Cognito 将 SAML 和 OIDC 提供商的用户声明自定义为短期证书的 API [AssumeRoleWithWebIdentity](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html)请求。 OAuth

Amazon Cognito 用户池类似于支持 SSO 的应用程序的 OIDC 身份提供者。对于具有最适合 IAM 授权的资源依赖关系的任何应用程序，身份池充当其 *AWS* 身份提供者。

Amazon Cognito 身份池支持以下身份提供商：
+ 公有提供商：[设置 Login with Amazon 作为身份池 IdP](amazon.md)、[将 Facebook 设置为身份池 IdP](facebook.md)、[将 Google 设置为身份池 IdP](google.md)、[使用 Apple 作为身份池 IdP 来设置登录](apple.md)、Twitter。
+ [Amazon Cognito 用户池](cognito-user-pools.md)
+ [设置 OIDC 提供者作为身份池 IdP](open-id.md)
+ [设置 SAML 提供者作为身份池 IdP](saml-identity-provider.md)
+ [经开发人员验证的身份](developer-authenticated-identities.md)

有关 Amazon Cognito 身份池区域可用性的信息，请参阅[AWS 服务区域可用性](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/)。

有关 Amazon Cognito 身份池的更多信息，请参阅以下主题。

**Topics**
+ [身份池控制台概述](identity-pools.md)
+ [身份池身份验证流程](authentication-flow.md)
+ [IAM 角色](iam-roles.md)
+ [Amazon Cognito 身份池的安全最佳实践](identity-pools-security-best-practices.md)
+ [将属性用于访问控制](attributes-for-access-control.md)
+ [使用基于角色的访问控制](role-based-access-control.md)
+ [获取凭证](getting-credentials.md)
+ [使用临时 AWS 服务 凭证进行访问](accessing-aws-services.md)
+ [身份池第三方身份提供者](external-identity-providers.md)
+ [经开发人员验证的身份](developer-authenticated-identities.md)
+ [将未经身份验证的用户切换为经过身份验证的用户](switching-identities.md)

# 身份池控制台概述
<a name="identity-pools"></a>

Amazon Cognito 身份池为访客用户（未经身份验证）和已通过身份验证并收到令牌的用户提供临时 AWS 证书。身份池是指与您的外部身份提供者关联的用户标识符的存储。

要了解身份池的特征和选项，一种方法是在 Amazon Cognito 控制台中创建一个身份池。您可以探索不同设置对身份验证流程、基于角色和基于属性的访问控制以及访客访问的影响。接下来，您可以继续阅读本指南的后面章节，并向您的应用程序添加相应的组件，以便可以实施身份池身份验证。

**Topics**
+ [创建 身份池](#identity-pools-create)
+ [用户 IAM 角色](#user-iam-roles)
+ [经过身份验证和未经身份验证的身份](#authenticated-and-unauthenticated-identities)
+ [激活或停用访客访问权限](#enable-or-disable-unauthenticated-identities)
+ [更改与身份类型关联的角色](#change-the-role-associated-with-an-identity-type)
+ [编辑身份提供者](#enable-or-edit-authentication-providers)
+ [删除身份池](#delete-an-identity-pool)
+ [从身份池删除身份](#delete-an-identity-from-an-identity-pool)
+ [将 Amazon Cognito Sync 与身份池一起使用](#identity-pools-sync)

## 创建 身份池
<a name="identity-pools-create"></a>

**在控制台中创建新的身份池**

1. 登录 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)并选择**身份池**。

1. 选择**创建身份池**。

1. 在**配置身份池信任**中，选择将您的身份池设置为**经过身份验证的访问权限**和/或**访客访问权限**。

   1. 如果您选择了**经过身份验证的访问权限**，请在身份池中选择一个或多个您要设置为经过身份验证的身份来源的**身份类型**。如果您配置了**自定义开发人员提供者**，则在创建身份池后无法对其进行修改或删除。

1. 在**配置权限**中，为身份池中经过身份验证的用户或访客用户选择原定设置 IAM 角色。

   1. 如果您希望 Amazon Cognito 为您创建一个具有基本权限并与您的身份池建立信任关系的新角色，请选择**创建新的 IAM 角色**。例如，输入 **IAM 角色名称**以标识您的新角色，例如 `myidentitypool_authenticatedrole`。选择**查看策略文档**以查看 Amazon Cognito 将分配给新 IAM 角色的权限。

   1. 如果您的 AWS 账户 角色中已有要**使用的角色，则可以选择使用现有 IAM** 角色。您必须将您的 IAM 角色信任策略配置为包括 `cognito-identity.amazonaws.com`。配置您的角色信任策略，以仅允许 Amazon Cognito 在提供证据证明请求来自您的特定身份池中经过身份验证的用户时，才代入该角色。有关更多信息，请参阅 [角色信任和权限](iam-roles.md#role-trust-and-permissions)。

1. 在 **Connect 身份提供商**中，输入您在**配置身份池信任中选择的身份**提供商 (IdPs) 的详细信息。系统可能会要求您提供 OAuth 应用程序客户端信息、选择 Amazon Cognito 用户池、选择 IAM IdP 或输入开发者提供商的自定义标识符。

   1. 为每个 IdP 选择**角色设置**。您可以为该 IdP 中的用户分配您在配置**经过身份验证的角色**时设置的**原定设置角色**，也可以**使用规则选择角色**。使用 Amazon Cognito 用户群体 IdP，还可以**选择令牌中包含 preferred\$1role 声明的角色**。有关 `cognito:preferred_role` 声明的更多信息，请参阅[将优先级值分配到组](cognito-user-pools-user-groups.md#assigning-precedence-values-to-groups)。

      1. 如果您选择**使用规则选择角色**，请输入用户身份验证中的来源**声明**、您要用来与声明进行比较的**运算符**、导致与该角色选择匹配的**值**，以及当**角色分配**匹配时要分配的**角色**。选择**添加其他**，以根据不同的条件创建其他规则。

      1. 选择**角色解析**。当用户的声明与您的规则不匹配时，您可以拒绝凭证或为**经过身份验证的角色**颁发凭证。

   1. 您可以为每个 IdP 配置**访问控制属性**。访问控制属性将用户声明映射到 Amazon Cognito 应用于其临时会话的[主体标签](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_iam-tags.html)。您可以构建 IAM policy，以根据应用于用户会话的标签来筛选用户访问权限。

      1. 如果不应用主体标签，请选择**非活动**。

      1. 要基于 `sub` 和 `aud` 声明应用主体标签，请选择**使用原定设置映射**。

      1. 要为主体标签创建自己的自定义属性模式，请选择**使用自定义映射**。然后，对于您要在标签中表示的每个**声明**，输入要从该声明中获取的**标签键**。

1. 在**配置属性**中，在**身份池名称**下输入**名称**。

1. 在**基本（经典）身份验证**下，选择是否要**激活基本流程**。启用基本流程后，您可以绕过为自己选择的角色 IdPs ，[AssumeRoleWithWebIdentity](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html)直接致电。有关更多信息，请参阅 [身份池身份验证流程](authentication-flow.md)。

1. 如果要将[标签](https://docs.aws.amazon.com/general/latest/gr/aws_tagging.html)应用到身份池，请在**标签**下选择**添加标签**。

1. 在**查看并创建**中，确认您为新身份池所做的选择。选择**编辑**以返回向导并更改任何设置。完成后，选择**创建身份池**。

## 用户 IAM 角色
<a name="user-iam-roles"></a>

IAM 角色定义用户访问 AWS 资源的权限，例如[Amazon Cognito Sync](cognito-sync.md)。您的应用程序用户将担任您创建的角色。您可以为经过身份验证和未经身份验证的用户指定不同角色。要了解有关 IAM 角色的更多信息，请参阅 [IAM 角色](iam-roles.md)。

## 经过身份验证和未经身份验证的身份
<a name="authenticated-and-unauthenticated-identities"></a>

Amazon Cognito 身份池同时支持经过身份验证和未经身份验证的身份。经过身份验证的身份属于已通过任何受支持的身份提供商进行身份验证的用户。未经身份验证的身份通常属于来宾用户。
+ 要使用公共登录提供商配置经过身份验证的身份，请参阅 [身份池第三方身份提供者](external-identity-providers.md)。
+ 要配置您自己的后端身份验证流程，请参阅 [经开发人员验证的身份](developer-authenticated-identities.md)。

## 激活或停用访客访问权限
<a name="enable-or-disable-unauthenticated-identities"></a>

 Amazon Cognito 身份池访客访问（未经身份验证的身份）为未向身份提供者进行身份验证的用户提供唯一标识符和 AWS 证书。如果应用程序允许未登录的用户进行访问，则您可以针对未经身份验证的身份激活访问权限。要了解更多信息，请参阅[Amazon Cognito 身份池入门](getting-started-with-identity-pools.md)。

**更新身份池中的访客访问权限**

1. 从 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)中选择**身份池**。选择身份池。

1. 选择**用户访问**选项卡。

1. 找到**访客访问权限**。在目前不支持访客访问的身份池中，**状态**为**非活动**。

   1. 如果**访客访问权限**处于**活动**状态并且您想将其停用，请选择**停用**。

   1. 如果**访客访问权限**处于**非活动**状态而您想要将其激活，请选择**编辑**。

      1. 为身份池中的访客用户选择原定设置 IAM 角色。

        1. 如果您希望 Amazon Cognito 为您创建一个具有基本权限并与您的身份池建立信任关系的新角色，请选择**创建新的 IAM 角色**。例如，输入 **IAM 角色名称**以标识您的新角色，例如 `myidentitypool_authenticatedrole`。选择**查看策略文档**以查看 Amazon Cognito 将分配给新 IAM 角色的权限。

        1. 如果您的 AWS 账户 角色中已有要**使用的角色，则可以选择使用现有 IAM** 角色。您必须将您的 IAM 角色信任策略配置为包括 `cognito-identity.amazonaws.com`。配置您的角色信任策略，以仅允许 Amazon Cognito 在提供证据证明请求来自您的特定身份池中经过身份验证的用户时，才代入该角色。有关更多信息，请参阅 [角色信任和权限](iam-roles.md#role-trust-and-permissions)。

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

        1. 要激活访客访问权限，请在**用户访问权限**选项卡中选择**激活**。

## 更改与身份类型关联的角色
<a name="change-the-role-associated-with-an-identity-type"></a>

身份池中的每个身份要么经过身份验证，要么未经过身份验证。经过身份验证的身份属于通过公共登录提供商（Amazon Cognito 用户池、Login with Amazon、Sign in with Apple、Facebook、Google、SAML 或任何 OpenID Connect 提供商）或开发人员提供商（自己的后端身份验证流程）验证身份的用户。未经身份验证的身份通常属于来宾用户。

每个身份类型都有一个分配的角色。此角色附有策略，规定 AWS 服务 该角色可以访问哪个角色。Amazon Cognito 接收请求后，服务将确定身份类型、确定分配给该身份类型的角色，并使用附加到该角色的策略进行响应。通过修改策略或为身份类型分配不同的角色，您可以控制哪些 AWS 服务 身份类型可以访问。要查看或修改与身份池中与角色关联的策略，请参阅 [AWS IAM 控制台](https://console.aws.amazon.com/iam/home)。

**更改身份池的原定设置经过身份验证或未经身份验证的角色**

1. 从 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)中选择**身份池**。选择身份池。

1. 选择**用户访问**选项卡。

1. 找到**访客访问权限**或**经过身份验证的访问权限**。在当前未为该访问类型配置的身份池中，**状态**为**非活动**。选择**编辑**。

1. 为身份池中的访客用户或经过身份验证的用户选择原定设置 IAM 角色。

   1. 如果您希望 Amazon Cognito 为您创建一个具有基本权限并与您的身份池建立信任关系的新角色，请选择**创建新的 IAM 角色**。例如，输入 **IAM 角色名称**以标识您的新角色，例如 `myidentitypool_authenticatedrole`。选择**查看策略文档**以查看 Amazon Cognito 将分配给新 IAM 角色的权限。

   1. 如果您的 AWS 账户 角色中已有要**使用的角色，则可以选择使用现有 IAM** 角色。您必须将您的 IAM 角色信任策略配置为包括 `cognito-identity.amazonaws.com`。配置您的角色信任策略，以仅允许 Amazon Cognito 在提供证据证明请求来自您的特定身份池中经过身份验证的用户时，才代入该角色。有关更多信息，请参阅 [角色信任和权限](iam-roles.md#role-trust-and-permissions)。

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

## 编辑身份提供者
<a name="enable-or-edit-authentication-providers"></a>

如果您允许用户通过使用者身份提供者（例如，Amazon Cognito 用户池、Login with Amazon、通过 Apple 登录、Facebook 或 Google）进行身份验证，则您可以在 Amazon Cognito 身份池（联合身份）控制台中指定应用程序标识符。上述操作会将应用程序 ID (由公共登录提供商提供) 与身份池关联。

您还可以从此页面为每个提供商配置身份验证规则。每个提供商最多可以有 25 个规则。规则按您为各个提供商保存的顺序应用。有关更多信息，请参阅 [使用基于角色的访问控制](role-based-access-control.md)。

**警告**  
更改身份池中关联的 IdP 应用程序 ID 可防止现有用户通过该身份池进行身份验证。有关更多信息，请参阅 [身份池第三方身份提供者](external-identity-providers.md)。

**更新身份池身份提供者（IdP）**

1. 从 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)中选择**身份池**。选择身份池。

1. 选择**用户访问**选项卡。

1. 找到**身份提供者**。选择要编辑的身份提供者。如果要添加新的 IdP，请选择**添加身份提供者**。

   1. 如果您选择**添加身份提供者**，请选择要添加的**身份类型**之一。

1. 要更改应用程序 ID，请在**身份提供者信息**中选择**编辑**。

1. 要更改 Amazon Cognito 在向通过该提供商进行身份验证的用户颁发凭证时请求的角色，请在**角色设置**中选择**编辑**。

   1. 您可以为该 IdP 中的用户分配您在配置**经过身份验证的角色**时设置的**原定设置角色**，也可以**使用规则选择角色**。使用 Amazon Cognito 用户群体 IdP，还可以**选择令牌中包含 preferred\$1role 声明的角色**。有关 `cognito:preferred_role` 声明的更多信息，请参阅[将优先级值分配到组](cognito-user-pools-user-groups.md#assigning-precedence-values-to-groups)。

     1. 如果您选择**使用规则选择角色**，请输入用户身份验证中的来源**声明**、您要用来与声明进行比较的**运算符**、导致与该角色选择匹配的**值**，以及当**角色分配**匹配时要分配的**角色**。选择**添加其他**，以根据不同的条件创建其他规则。

     1. 选择**角色解析**。当用户的声明与您的规则不匹配时，您可以拒绝凭证或为**经过身份验证的角色**颁发凭证。

1. 要更改 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时分配的主体标签，请在**访问控制属性**中选择**编辑**。

   1. 如果不应用主体标签，请选择**非活动**。

   1. 要基于 `sub` 和 `aud` 声明应用主体标签，请选择**使用原定设置映射**。

   1. 要为主体标签创建自己的自定义属性模式，请选择**使用自定义映射**。然后，对于您要在标签中表示的每个**声明**，输入要从该声明中获取的**标签键**。

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

## 删除身份池
<a name="delete-an-identity-pool"></a>

您不能撤销身份池删除。删除身份池后，所有依赖该身份池的应用程序和用户将停止工作。

**删除身份池**

1. 从 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)中选择**身份池**。选中要删除的身份池旁边的单选按钮。

1. 选择**删除**。

1. 输入或粘贴身份池的名称，然后选择**删除**。

**警告**  
选择删除按钮后，您将永久删除身份池和其中包含的所有用户数据。删除身份池将导致使用身份池的应用程序和其他服务停止工作。

## 从身份池删除身份
<a name="delete-an-identity-from-an-identity-pool"></a>

当您从身份池中删除身份时，您会删除 Amazon Cognito 为该联合用户存储的身份信息。当用户再次请求凭证时，如果身份池仍然信任用户的身份提供者，则用户会收到新的身份 ID。您无法撤销此操作。

**删除身份**

1. 从 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)中选择**身份池**。选择身份池。

1. 选择**身份浏览器**选项卡。

1. 选中要删除的身份旁边的复选框，然后选择**删除**。确认您要删除这些身份，然后选择**删除**。

## 将 Amazon Cognito Sync 与身份池一起使用
<a name="identity-pools-sync"></a>

 Amazon Cognito Sync 是一个 AWS 服务 和客户端库，它使跨设备同步与应用程序相关的用户数据成为可能。Amazon Cognito 可以跨移动设备和 Web 同步用户配置文件数据，无需使用您自己的后端。客户端库在本地缓存数据，因此，您的应用程序可以读取和写入数据，无论设备是否处于连接状态，都是如此。设备处于在线状态时，您可以同步数据。如果您设置推送同步，您可在更新可用时立即通知其他设备。

### 管理数据集
<a name="managing-datasets-in-the-amazon-cognito-console"></a>

如果您在应用程序中实施了 Amazon Cognito Sync 功能，则 Amazon Cognito 身份池控制台允许您手动创建和删除各个身份的数据集和记录。对于您在 Amazon Cognito 身份池控制台中对身份的数据集或记录做出的任何更改，只有当您在控制台中选择 **Synchronize**（同步）后才会保存。直到身份调用 **Synchronize**（同步）后，终端用户才能看到更改。一旦刷新特定身份的列表数据集页面，从其它设备同步的有关各个身份的数据即会显示。

#### 为身份创建数据集
<a name="create-a-dataset-for-an-identity"></a>

Amazon Cognito Sync 将数据集与一个身份关联起来。您可以在数据集中填充该身份所代表的用户的身份信息，然后将该信息同步到用户的所有设备。

**将数据集和数据集记录添加到身份**

1. 从 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)中选择**身份池**。选择身份池。

1. 选择**身份浏览器**选项卡。

1. 选择要编辑的身份。

1. 在**数据集**中，选择**创建数据集**。

1. 输入**数据集名称**并选择**创建数据集**。

1. 如果您想向数据集添加记录，请从身份详细信息中选择您的数据集。在**记录**中，选择**创建记录**。

1. 输入记录的**键**和**值**。选择**确认**。重复此操作以添加更多记录。

#### 删除与身份关联的数据集
<a name="delete-a-dataset-associated-with-an-identity"></a>

**从身份中删除数据集及其记录**

1. 从 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)中选择**身份池**。选择身份池。

1. 选择**身份浏览器**选项卡。

1. 选择包含要删除的数据集的身份。

1. 在**数据集**中，选择要删除的数据集旁边的单选按钮。

1. 选择**删除**。查看您的选择，然后再次选择**删除**。

### 批量发布数据
<a name="bulk-publish-data"></a>

 批量发布可用于将存储在 Amazon Cognito Sync 存储中的数据导出到 Amazon Kinesis Stream。有关如何批量发布所有流的说明，请参阅 [实施 Amazon Cognito Sync 流](cognito-streams.md)。

### 激活推送同步
<a name="enable-push-synchronization"></a>

 Amazon Cognito 会自动跟踪身份和设备之间的关联。通过使用推送同步功能，可以确保在身份数据发生更改时通知给定身份的每个实例。推送同步可以确保，只要身份的数据集发生更改，与该身份关联的所有设备就会收到一个静音推送通知，通知它们所发生的更改。

 您可以在 Amazon Cognito 控制台中激活推送同步。

**激活推送同步**

1. 从 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)中选择**身份池**。选择身份池。

1. 选择**身份池属性**选项卡。

1. 在**推送同步**中，选择**编辑**

1. 选择**激活与身份池的推送同步**。

1. 选择您在当前 AWS 区域中创建的 Amazon Simple Notiﬁcation Service（Amazon SNS）**平台应用程序**之一。Amazon Cognito 向您的平台应用程序发布推送通知。选择**创建平台应用程序**以导航到 Amazon SNS 控制台并创建一个新的应用程序。

1. 要发布到平台应用程序，Amazon Cognito 将代入您的 AWS 账户中的 IAM 角色。如果您希望 Amazon Cognito 为您创建一个具有基本权限并与您的身份池建立信任关系的新角色，请选择**创建新的 IAM 角色**。例如，输入 **IAM 角色名称**以标识您的新角色，例如 `myidentitypool_authenticatedrole`。选择**查看策略文档**以查看 Amazon Cognito 将分配给新 IAM 角色的权限。

1. 如果您的 AWS 账户 角色中已有要**使用的角色，则可以选择使用现有 IAM** 角色。您必须将您的 IAM 角色信任策略配置为包括 `cognito-identity.amazonaws.com`。配置您的角色信任策略，以仅允许 Amazon Cognito 在提供证据证明请求来自您的特定身份池中经过身份验证的用户时，才代入该角色。有关更多信息，请参阅 [角色信任和权限](iam-roles.md#role-trust-and-permissions)。

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

### 设置 Amazon Cognito Streams
<a name="set-up-cognito-streams"></a>

 Amazon Cognito Streams 让开发人员能够控制和了解他们存储在 Amazon Cognito Sync 中的数据。开发人员现在可以配置 Kinesis 流以接收数据形式的事件。Amazon Cognito 可以实时向您拥有的 Kinesis 流推送每个数据集更改。有关如何在 Amazon Cognito 控制台中设置 Amazon Cognito Streams 的说明，请参阅[实施 Amazon Cognito Sync 流](cognito-streams.md)。

### 设置 Amazon Cognito Events
<a name="set-up-cognito-events"></a>

 Amazon Cognito Events 允许您运行 AWS Lambda 函数以响应 Amazon Cognito Sync 中的重要事件。当数据集得到同步时，Amazon Cognito Sync 会引发同步触发事件。当用户更新数据时，您可以使用同步触发事件采取行动。有关从控制台设置 Amazon Cognito Events 的说明，请参阅[使用 Amazon Cognito Events 自定义工作流](cognito-events.md)。

 要了解更多信息 AWS Lambda，请参阅[AWS Lambda](https://aws.amazon.com/lambda/)。

# 身份池身份验证流程
<a name="authentication-flow"></a>

Amazon Cognito 可帮助您为终端用户创建在多个设备和平台间保持一致的唯一标识符。Amazon Cognito 还会向您的应用程序提供临时的、权限有限的凭证以访问资源。 AWS 此页面介绍有关 Amazon Cognito 中的身份验证如何工作的基础知识，并解释了身份池中身份的生命周期。

**外部提供商身份验证流程**

使用 Amazon Cognito 进行身份验证的用户将通过一个多步骤流程来引导启动其凭证。Amazon Cognito 提供两个不同的通过公有提供商进行身份验证的流程：增强型流程和基本流程。

完成其中一个流程后，您可以访问由您的角色访问策略定义的其他 AWS 服务 流程。默认情况下，[Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/)创建可访问 Amazon Cognito Sync 存储和 Amazon Mobile Analytics 的角色。有关如何授予额外访问权限的更多信息，请参阅 [IAM 角色](iam-roles.md)。

身份池接受来自提供商的以下构件：


| Provider | 身份验证构件 | 
| --- | --- | 
| Amazon Cognito 用户池 | ID 令牌 | 
| OpenID Connect（OIDC） | ID 令牌 | 
| SAML 2.0 | SAML 断言 | 
| 社交提供商 | 访问令牌 | 

## 增强（简化）的身份验证流程
<a name="authentication-flow-enhanced"></a>

当您使用增强版身份验证流程时，您的应用程序会首先在请求中提供来自授权的 Amazon Cognito 用户池或第三方身份提供商的身份验证证明。[GetId](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetId.html)

1. 您的应用程序显示 [GetId](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetId.html) 请求中来自已授权 Amazon Cognito 用户池或第三方身份提供者的身份验证证明（JSON Web 令牌或 SAML 断言）。

1. 您的身份池返回身份 ID。

1. 您的应用程序在[GetCredentialsForIdentity](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetCredentialsForIdentity.html)请求中将身份 ID 与相同的身份验证证明相结合。

1. 您的身份池会返回 AWS 证书。

1. 您的应用程序使用临时证书签署 AWS API 请求。

增强型身份验证管理您的身份池配置中的 IAM 角色选择和凭证检索的逻辑。您可以配置身份池以选择默认角色，将基于属性的访问权限控制（ABAC）或基于角色的访问权限控制（RBAC）原则应用于角色选择。来自增强身份验证的 AWS 凭证有效期为一小时。

**增强型身份验证中的操作顺序**

1. `GetId`

1. `GetCredentialsForIdentity`

![\[显示了增强型身份验证流程的示意图\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/amazon-cognito-ext-auth-enhanced-flow.png)


## 基本（经典）身份验证流程
<a name="authentication-flow-basic"></a>

在实施基本身份验证流程时，您的应用程序会选择您希望用户代入的 IAM 角色。

1. 您的应用程序显示 [GetId](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetId.html) 请求中来自已授权 Amazon Cognito 用户池或第三方身份提供者的身份验证证明（JSON Web 令牌或 SAML 断言）。

1. 您的身份池返回身份 ID。

1. 您的应用程序在[GetOpenIdToken](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetOpenIdToken.html)请求中将身份 ID 与相同的身份验证证明相结合。

1. `GetOpenIdToken`返回由您的身份池颁发的新 OAuth 2.0 令牌。

1. 您的应用程序在[AssumeRoleWithWebIdentity](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html)请求中显示新令牌。

1. AWS Security Token Service (AWS STS) 返回 AWS 凭证。

1. 您的应用程序使用临时证书签署 AWS API 请求。

通过基本型工作流，您可以更精细地控制分发给用户的凭证。增强型身份验证流程的 `GetCredentialsForIdentity` 请求根据访问令牌的内容请求角色。经典工作流程中的`AssumeRoleWithWebIdentity`请求使您的应用程序能够更好地请求您配置了足够信任策略的任何 AWS Identity and Access Management 角色的凭证。您也可以请求自定义角色会话持续时间。

您可以在没有角色映射的用户池中使用基本身份验证流程进行登录。这种类型的身份池没有默认的已验证角色或未经身份验证的角色，也没有配置基于角色或基于属性的访问控制。当您在使用角色映射的身份池中尝试 `GetOpenIdToken` 时，会收到以下错误。

```
Basic (classic) flow is not supported with RoleMappings, please use enhanced flow.
```

**基本身份验证中的操作顺序**

1. `GetId`

1. `GetOpenIdToken`

1. `AssumeRoleWithWebIdentity`

![\[显示了基本身份验证流程的示意图\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/amazon-cognito-ext-auth-basic-flow.png)


## 经过开发者身份验证的身份验证流程
<a name="authentication-flow-developer"></a>

使用[经开发人员验证的身份](developer-authenticated-identities.md)时，您的客户端将使用包括 Amazon Cognito 外部代码的不同身份验证流程，在您自己的身份验证系统中验证用户。从您的身份池的角度来看，您在身份请求中提出的声明是任意标识符，并且身份验证由您在应用程序中编码的 IAM 凭证进行授权。

**开发人员提供商的增强型身份验证中的操作顺序**

1. 通过开发人员提供商登录（Amazon Cognito 外部代码）

1. 验证用户登录（Amazon Cognito 外部代码）

1. [GetOpenIdTokenForDeveloperIdentity](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetOpenIdTokenForDeveloperIdentity.html)

1. [GetCredentialsForIdentity](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetCredentialsForIdentity.html)

![\[一个示意图，显示了经开发人员验证身份的增强型身份验证流程\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/amazon-cognito-dev-auth-enhanced-flow.png)


**开发人员提供商的基本身份验证中的操作顺序**

1. 在身份池之外实施逻辑来登录，并生成开发人员提供商标识符。

1. 检索存储的服务器端 AWS 凭证。

1. 在使用授权 AWS 凭证签名[GetOpenIdTokenForDeveloperIdentity](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetOpenIdTokenForDeveloperIdentity.html)的 API 请求中发送开发者提供商标识符。

1. 使用请求应用程序凭证[AssumeRoleWithWebIdentity](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html)。

![\[一个示意图，显示了经开发人员验证身份的基本身份验证流程\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/amazon-cognito-dev-auth-basic-flow.png)


## 我应该实施哪个身份验证流程？
<a name="authentication-flow-choosing"></a>

**增强型流程**是更安全的选择，开发人员的工作量更少：
+ 增强型流程降低了 API 请求的复杂性、大小和频率。
+ 您的应用程序无需向 AWS STS发出其他 API 请求。
+ 您的身份池会评估您的用户应收到的 IAM 角色凭证。您无需在客户端中嵌入用于角色选择的逻辑。

**重要**  
创建新的身份池时，最好不要默认激活基本（经典）身份验证。要实施基本身份验证，请先评估您的 IAM 角色与 Web 身份之间的信任关系。然后在您的客户端中构建角色选择逻辑，并保护客户端不被用户修改。

**基本身份验证流程**将 IAM 角色选择的逻辑委托给您的应用程序。在此流程中，Amazon Cognito 会验证您的用户经过身份验证或未经身份验证的会话，并颁发一个令牌，您可以用该令牌交换证书。 AWS STS用户可以将基本身份验证中的令牌交换为信任您的身份池和 `amr` /或 authenticated/unauthenticated 状态的任何 IAM 角色。

同样，您要明白，**开发人员身份验证**是一种绕过身份提供者身份验证的快捷方式。Amazon Cognito 信任授权[GetOpenIdTokenForDeveloperIdentity](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetOpenIdTokenForDeveloperIdentity.html)请求的 AWS 凭证，无需对请求内容进行额外验证。保护用于授权开发人员身份验证的密钥，防止用户访问这些信息。

## 身份验证流程 API 操作概述
<a name="authentication-flow-operations"></a>

**GetId**  
[GetId](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetId.html) API 调用是在 Amazon Cognito 中建立新身份所必需的第一个调用。    
未经身份验证的访问  
Amazon Cognito 能够在您的应用程序中授权未经身份验证的访客访问。如果您的身份池中已启用此功能，用户可以随时通过 `GetId` API 请求新的身份 ID。该应用程序应缓存此身份 ID，以对 Amazon Cognito 发出后续调用。 AWS 移动设备 SDKs 和浏览器 JavaScript 中的 S AWS DK 都有凭据提供商，可以为您处理缓存。  
经过身份验证的访问  
当你将应用程序配置为支持公共登录提供商（Facebook、Google\$1、使用亚马逊登录或用苹果登录）时，用户还可以提供令牌（或 OAuth OpenID Connect），用于在这些提供商中识别他们。在对 `GetId` 的调用中使用时，Amazon Cognito 创建一个经过身份验证的新身份，或者是返回已与该特定登录关联的身份。Amazon Cognito 通过向提供商验证令牌并确保以下各项来实现此目的：  
+ 令牌有效且来自已配置的提供商。
+ 令牌未过期。
+ 令牌与使用该提供商创建的应用程序标识符（如 Facebook 应用程序 ID）匹配。
+ 令牌与用户标识符匹配。

**GetCredentialsForIdentity**  
在建立身份 ID 后，即可调用 [GetCredentialsForIdentity](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetCredentialsForIdentity.html) API。因此，此操作在功能上等同于调用[GetOpenIdToken](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetOpenIdToken.html)。[AssumeRoleWithWebIdentity](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html)  
要让 Amazon Cognito 代表您调用 `AssumeRoleWithWebIdentity`，您的身份池必须具有与之关联的 IAM 角色。为此，您可以使用 Amazon Cognito 控制台，也可以通过 [SetIdentityPoolRoles](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_SetIdentityPoolRoles.html) 手动操作实现此目的。

**GetOpenIdToken**  
在建立身份 ID 后，即可发出 [GetOpenIdToken](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetOpenIdToken.html) API 请求。 IDs 在您第一次请求后缓存身份，然后使用启动该身份的后续基本（经典）会话`GetOpenIdToken`。  
对 `GetOpenIdToken` API 请求的响应是 Amazon Cognito 生成的令牌。您可以将此令牌作为 [AssumeRoleWithWebIdentity](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html) 请求中的 `WebIdentityToken` 参数提交。  
在提交 OpenID 令牌之前，请在您的应用程序中进行验证。您可以使用 SDK 中的 OIDC 库或类似于 [https://github.com/awslabs/aws-jwt-verify](https://github.com/awslabs/aws-jwt-verify) 的库来确认 Amazon Cognito 颁发了令牌。OpenID 令牌的签名密钥 ID 或 `kid` 是 Amazon Cognito 身份 [jwks\$1uri 文档](https://cognito-identity.amazonaws.com/.well-known/jwks_uri)中列出的密钥之一。这些密钥可能会发生变化。验证 Amazon Cognito 身份令牌的函数应定期更新它在 *jwks\$1uri* 文档中的密钥列表。Amazon Cognito 在 *jwks\$1uri* 缓存控制响应标头中设置刷新时长，而 `max-age` 当前设置为 30 天。    
未经身份验证的访问  
要为未经身份验证的身份获取令牌，您只需身份 ID 本身。无法为经身份验证的身份或已停用的身份获取未经身份验证的令牌。  
经过身份验证的访问  
如果您有一个经过身份验证的身份，您必须为已与该身份关联的登录名传递至少一个令牌。在 `GetOpenIdToken` 调用期间，所有传入的令牌都必须通过之前提到的同一验证；如果有任何令牌失败，整个调用都会失败。`GetOpenIdToken` 调用的响应中还包括身份 ID。这是因为您传入的身份 ID 可能不是返回的那个身份 ID。  
关联登录名  
如果您为尚未与任何身份关联的登录名提交令牌，该登录名将视为已“关联”到关联身份。您只能为每个公共提供商链接一个登录名。如果尝试将多个登录名链接到一个公共提供商，将导致 `ResourceConflictException` 错误响应。如果登录名只链接到一个现有身份，则 `GetOpenIdToken` 返回的身份 ID 将与传入的相同。  
合并身份  
如果您为目前未链接到给定身份，但链接到另一身份的登录名传入令牌，这两个身份将合并。合并后，一个身份成为所有关联登录 parent/owner 名中的一个，另一个身份被禁用。在这种情况下，将返回的 parent/owner 身份 ID。如果此值不同，则必须更新本地缓存。 AWS 移动版 SDKs 或浏览器版 AWS SDK JavaScript 中的提供商会为您执行此操作。

**GetOpenIdTokenForDeveloperIdentity**  
当使用经过开发者身份验证[GetId](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetId.html)的[GetOpenIdToken](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetOpenIdToken.html)身份时，该[GetOpenIdTokenForDeveloperIdentity](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetOpenIdTokenForDeveloperIdentity.html)操作取代了对设备的使用。由于您的应用程序使用 AWS 凭证签署此 API 操作的请求，Amazon Cognito 相信请求中提供的用户标识符有效。开发人员身份验证会替代 Amazon Cognito 对外部提供商执行的令牌验证。  
此 API 的有效载荷包括 `logins` 映射。此映射必须包含您的开发人员提供商密钥，以及作为系统中用户标识符的值。如果用户标识符尚未关联到现有身份，Amazon Cognito 会创建新的身份，并为该身份返回新身份 ID 以及 OpenID Connect 令牌。如果用户标识符已关联，Amazon Cognito 返回预先存在的身份 ID 和 OpenID Connect 令牌。 IDs在您第一次请求后缓存开发者身份，然后使用启动该身份的后续基本（经典）会话`GetOpenIdTokenForDeveloperIdentity`。  
对 `GetOpenIdTokenForDeveloperIdentity` API 请求的响应是 Amazon Cognito 生成的令牌。您可以将此令牌作为 `AssumeRoleWithWebIdentity` 请求中的 `WebIdentityToken` 参数提交。  
在提交 OpenID Connect 令牌之前，请在您的应用程序中进行验证。您可以使用 SDK 中的 OIDC 库或类似于 [https://github.com/awslabs/aws-jwt-verify](https://github.com/awslabs/aws-jwt-verify) 的库来确认 Amazon Cognito 颁发了令牌。OpenID Connect 令牌的签名密钥 ID 或 `kid` 是 Amazon Cognito 身份 [*jwks\$1uri* 文档](https://cognito-identity.amazonaws.com/.well-known/jwks_uri)中列出的密钥之一。这些密钥可能会发生变化。验证 Amazon Cognito 身份令牌的函数应定期更新它在 *jwks\$1uri* 文档中的密钥列表。Amazon Cognito 在 *jwks\$1uri* `cache-control` 响应标头中设置刷新时长，`max-age` 当前设置为 30 天。    
关联登录名  
与外部提供商一样，提供尚未与身份关联的额外登录名会将这些登录名隐式关联到该身份。如果您将一个外部提供商登录名链接到一个身份，用户可以对该提供商使用外部提供商身份验证流程。但是，他们无法在调用 `GetId` 或 `GetOpenIdToken` 时使用登录映射中的开发人员提供商名称。  
合并身份  
借助已经过开发人员验证的身份，Amazon Cognito 支持隐式合并以及通过 [MergeDeveloperIdentities](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_MergeDeveloperIdentities.html) API 进行显式合并。通过显式合并，您可以使用系统中的用户标识符将两个身份标记为单个身份。如果您提供了源和目标用户标识符，Amazon Cognito 会将其合并。您下次为任一用户标识符请求 OpenID Connect 令牌时，系统都会返回同一身份 ID。

**AssumeRoleWithWebIdentity**  
在你获得 OpenID Connect 令牌后，你可以通过 [AssumeRoleWithWebIdentity](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html)API 请求将其换成临时 AWS 证书 AWS Security Token Service ()AWS STS。  
由于可以创建的身份数量没有限制，所以您务必要了解向用户授予的权限。为应用程序设置不同的 IAM 角色：一个用于未经身份验证的用户，一个用于经过身份验证的用户。当您首次设置身份池时，Amazon Cognito 控制台会创建默认角色。实际上没有向这些角色授予任何权限。修改这些角色以满足您的需求。  
了解有关 [角色信任和权限](iam-roles.md#role-trust-and-permissions) 的更多信息。

† 原定设置 Amazon Cognito 身份 [https://cognito-identity.amazonaws.com/.well-known/jwks_uri](https://cognito-identity.amazonaws.com/.well-known/jwks_uri) 文档包含有关在大多数 AWS 区域中用于签署身份池令牌的密钥的信息。以下区域有不同的 *jwks\$1uri* 文档。


| AWS 区域 | *jwks\$1uri* 文档的路径 | 
| --- |--- |
| AWS GovCloud （美国西部） | https://cognito-identity.us-gov-west-1.amazonaws.com/.well-known/jwks\$1uri | 
| 中国（北京） | https://cognito-identity---cn-north-1.amazonaws.com.rproxy.govskope.ca.cn/.well-known/jwks\$1uri | 
| 欧洲（米兰）和非洲（开普敦）等选择加入区域 | https://cognito-identity.Region.amazonaws.com/.well-known/jwks\$1uri | 

您还可以从颁发者推断出 *jwks\$1uri*，或者从 Amazon Cognito 推断出在 OpenID 令牌中收到的 `iss`。OIDC 标准发现端点 `<issuer>/.well-known/openid-configuration` 列出了您的令牌的 *jwks\$1uri* 的路径。

# IAM 角色
<a name="iam-roles"></a>

在创建身份池时，系统会提示您更新用户代入的 IAM 角色。IAM 角色的工作方式如下：当用户登录应用程序时，Amazon Cognito 为用户生成临时 AWS 凭证。这些临时凭证与特定 IAM 角色相关联。通过 IAM 角色，您可以定义一组权限，用来访问您的 AWS 资源。

您可以为经过身份验证的用户和未经身份验证的用户指定默认 IAM 角色。此外，您可以定义规则，以便基于用户 ID 令牌中的声明为每个用户选择角色。有关更多信息，请参阅 [使用基于角色的访问控制](role-based-access-control.md)。

默认情况下，Amazon Cognito 控制台将创建可提供访问 Amazon Mobile Analytics 和 Amazon Cognito Sync 的权限的角色。或者，您也可以选择使用现有的 IAM 角色。

修改 IAM 角色以允许或限制对其他服务的访问。为此，请[登录 IAM 控制台](https://console.aws.amazon.com/iam/home)。然后，选择 **Roles**（角色），选择一个角色。**Permissions**（权限）选项卡中会列出选定角色所附加的策略。您可以选择相应的 **Manage Policy**（管理策略）链接自定义访问策略。要了解如何使用和定义策略的更多信息，请参阅 [IAM 策略概述](https://docs.aws.amazon.com/IAM/latest/UserGuide/PoliciesOverview.html)。

**注意**  
作为最佳实践，定义策略时应遵循授予*最低权限*的原则。换言之，策略只包含用户执行其任务所需的权限。有关更多信息，请参阅 *IAM 用户指南*中的[授予最低权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)。  
请记住，未经验证的身份会被未登录应用的用户所利用。通常情况下，为未经验证的身份分配的权限应该比为经过验证的身份分配的权限更严格。

**Topics**
+ [设置信任策略](#trust-policies)
+ [访问策略](#access-policies)
+ [角色信任和权限](#role-trust-and-permissions)

## 设置信任策略
<a name="trust-policies"></a>

Amazon Cognito 使用 IAM 角色为应用程序的用户生成临时凭证。对权限的访问由角色的信任关系控制。了解有关 [角色信任和权限](#role-trust-and-permissions) 的更多信息。Amazon Cognito 代理 AWS STS 和身份池之间的连接。 IdPs

呈现给 AWS STS 的令牌由身份池生成，身份池将用户池、社交或 OIDC 提供商令牌或 SAML 断言转换为自己的令牌。身份池令牌包含一个 `aud` 声明，即身份池 ID。

如果 IAM 角色信任策略的 `Principal` 是诸如 `cognito-identity.amazonaws.com` 的身份池服务主体，则您无法创建或修改角色信任策略以允许任何身份池代入该角色。对于身份池主体，`Action` 元素必须具有 `Condition`，要求 `AssumeRoleWithWebIndentity` 只能由您的身份池执行，正如诸如 `cognito-identity.amazonaws.com:aud` 的条件密钥所指定的。其他条件密钥也可用，但 `aud` 是必需的。如果您尝试保存没有此类条件的角色信任策略，IAM 会返回错误。

有关 OIDC（Web 身份）联合密钥的更多信息，请参阅 [AWS OIDC 联合身份验证的可用密钥](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#condition-keys-wif)。

以下是 Amazon Cognito 的可用 OIDC 联合身份验证条件密钥。

**`cognito-identity.amazonaws.com:aud`**  
将角色限制为从一个或多个身份池执行操作。Amazon Cognito 在身份池令牌的 `aud` 声明中标明了源身份池。

**`cognito-identity.amazonaws.com:amr`**  
将角色限制为 `authenticated` 或 `unauthenticated`（访客）用户。Amazon Cognito 在身份池令牌的 `amr` 声明中标明了身份验证状态。

**`cognito-identity.amazonaws.com:sub`**  
通过 [UUID](cognito-terms.md#terms-uuid) 将角色限制为一个或多个用户。此 UUID 是用户在身份池中的身份 ID。此值不是来自用户的原始身份提供者的 `sub` 值。Amazon Cognito 在身份池令牌的 `sub` 声明中标明了此 UUID。

以下示例角色信任策略允许联合服务主体`cognito-identity.amazonaws.com`调用 AWS STS API `AssumeRoleWithWebIdentity`。仅当 API 请求中的身份池令牌具有以下声明时，请求才会成功。

1. 一个 `aud` 声明（身份池 ID `us-west-2:abcdefg-1234-5678-910a-0e8443553f95`）。

1. 一个 `amr` 声明（`authenticated`），当用户已登录并且不是访客用户时添加。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "cognito-identity.amazonaws.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "cognito-identity.amazonaws.com:aud": "us-west-2:abcdefg-1234-5678-910a-0e8443553f95"
                },
                "ForAnyValue:StringLike": {
                    "cognito-identity.amazonaws.com:amr": "authenticated"
                }
            }
        }
    ]
}
```

------

### 基本（经典）身份验证中 IAM 角色的信任策略
<a name="trust-policies-classic"></a>

**Summary**  
只有当目标角色的信任策略包含 `aud` 条件时，身份池才能在[基本身份验证流程](authentication-flow.md#authentication-flow-basic)中代表用户扮演角色。

基本身份验证对不安全的角色信任策略的限制与增强型身份验证相同：您无法保存未使用 `aud` 条件对受支持的身份池进行限制的角色信任策略。服务启动时并未强制执行此限制。在强制执行此要求之前，您可以创建没有其他安全条件的角色信任策略。强制执行此要求后， AWS STS 允许 Web 身份扮演不受条件保护的角色，但是如果不引入这些条件，**则无法修改**这些角色。

增强型流程身份验证要求 IAM 角色与身份池在同一个 AWS 账户 中。但是在基本身份验证中，即您的应用程序撰写 `AssumeRoleWithWebIdentity` 请求时，它可以请求代入另一个账户中的角色。但是，如果目标角色的旧信任策略不强制执行 `aud` 条件，则您的[跨账户](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies-cross-account-resource-access.html)代入角色的请求将失败。

身份池为身份发放的令牌包含有关身份池来源 AWS 账户 的信息。当您在 [AssumeRoleWithWebIdentity](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html)API 请求中提供身份池令牌时， AWS STS 会检查原始身份池是否与 IAM 角色 AWS 账户 相同。如果 AWS STS 确定请求是跨账户的，则它会检查角色信任策略是否有`aud`条件。如果角色信任策略中不存在此类条件，则 **assume-role 调用会失败**。如果请求不是跨账户请求，则 AWS STS 不强制执行此限制。作为一种安全的最佳实践，应始终将此类条件应用于您的身份池角色的信任策略。

以下是一个信任策略示例，它满足 IAM 角色在与多个身份池配合使用时进行基本身份验证的*最低* 要求。作为最佳实践，还应通过 `"cognito-identity.amazonaws.com:amr": "authenticated"` 条件，仅允许已经过身份验证的身份。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "cognito-identity.amazonaws.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "cognito-identity.amazonaws.com:aud": [
                        "us-west-2:abcdefg-1234-5678-910a-0e8443553f95",
                        "us-west-2:hijklmo-5678-9101-112b-0e4221776g96",
                        "us-west-2:pqrstuv-9101-1121-314c-0e2110887h97"
                    ]
                }
            }
        }
    ]
}
```

------

### 其他信任策略条件
<a name="trust-policies-examples"></a>

您可以使用以下信任策略条件来定义能够代入 IAM 角色的源身份池、身份和提供商。

**注意**  
不要在身份池在[增强身份验证流程](authentication-flow.md#authentication-flow-enhanced)中承担的 IAM 角色的信任策略中实现[aws:SourceIp](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceip)条件密钥。由于增强型流程代表您的应用程序生成[AssumeRoleWithWebIdentity](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html)请求，因此请求的源 IP 将不是您的应用程序客户端的 IP，并且永远不会满足条件。基于网络的条件密钥*仅* 适用于身份池通过[基本流程](authentication-flow.md#authentication-flow-basic)代入的角色，因为基本流程不具备增强型流程的服务端功能。

**跨身份池重复使用角色**  
要跨多个身份池重复使用某个角色，由于它们共享一个通用权限集，您可以添加多个身份池，如下所示：

```
"StringEquals": {
    "cognito-identity.amazonaws.com:aud": [
        "us-east-1:12345678-abcd-abcd-abcd-123456790ab",
        "us-east-1:98765432-dcba-dcba-dcba-123456790ab"
    ]
}
```

**限制对特定身份的访问权限**  
要创建限制为一组特定应用用户的策略，请检查 `cognito-identity.amazonaws.com:sub` 的值：

```
"StringEquals": {
    "cognito-identity.amazonaws.com:aud": "us-east-1:12345678-abcd-abcd-abcd-123456790ab",
    "cognito-identity.amazonaws.com:sub": [
        "us-east-1:12345678-1234-1234-1234-123456790ab",
        "us-east-1:98765432-1234-1234-1243-123456790ab"
    ]
}
```

**限制对特定提供商的访问权限**  
要创建仅限于已使用特定提供商 (可能是您自己的登录提供商) 登录的用户的策略，请检查 `cognito-identity.amazonaws.com:amr` 的值：

```
"ForAnyValue:StringLike": {
    "cognito-identity.amazonaws.com:amr": "login.myprovider.myapp"
}
```

例如，一个仅信任 Facebook 的应用程序将具有以下 amr 子句：

```
"ForAnyValue:StringLike": {
    "cognito-identity.amazonaws.com:amr": "graph.facebook.com"
}
```

## 访问策略
<a name="access-policies"></a>

您附加到某个角色的权限适用于代入该角色的所有用户。为区分用户的访问权限，请使用策略条件和变量。有关更多信息，请参阅 [IAM policy 元素：变量和标签](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html)。您可以使用该`sub`条件在访问策略中限制对 Amazon Cognito 身份 IDs 的操作。请谨慎使用此选项，特别是对于未经身份验证的身份，因为这些身份缺少一致的用户 ID。有关使用 Amazon Cognito 进行网络联合的 IAM 策略变量的更多信息，请参阅*AWS Identity and Access Management 用户*指南[中的 IAM 和 AWS STS 条件上下文密钥](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#condition-keys-wif)。

为提供更好的安全保护，Amazon Cognito 使用 `GetCredentialsForIdentity`，对在[增强型流程](https://docs.aws.amazon.com/cognito/latest/developerguide/authentication-flow.html)中分配给未经身份验证用户的凭证应用缩小范围策略。缩小范围策略可向您对未经身份验证的角色应用的 IAM policy 添加 [内联会话策略](#access-policies-inline-policy) 和 [AWS 托管会话策略](#access-policies-managed-policy)。由于您必须在角色的 IAM policy 和会话策略中授予访问权限，因此，范围缩小策略限制了用户对以下服务列表以外的服务的访问权限。

**注意**  
在基本（经典）流程中，您可以发出自己的 [https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html) API 请求，并可以将这些限制应用于请求。作为最佳安全实践，请勿向未经身份验证的用户分配超出此缩小范围策略的任何权限。

Amazon Cognito 还可防止经过身份验证和未经身份验证的用户向 Amazon Cognito 身份池和 Amazon Cognito Sync 发出 API 请求。其他人 AWS 服务 可能会限制通过 Web 身份访问服务。

在使用增强型流程的成功请求中，Amazon Cognito 在后台发出 `AssumeRoleWithWebIdentity` API 请求。在此请求的参数中，Amazon Cognito 包括以下内容。

1. 用户的身份 ID。

1. 用户所需要代入的 IAM 角色的 ARN。

1. 一个 `policy` 参数，添加*内联会话策略*。

1. 一个`PolicyArns.member.N`参数，其值为在 Amazon 中授予额外权限的*AWS 托管策略* CloudWatch。

### 未经身份验证的用户可以访问的服务
<a name="access-policies-scope-down-services"></a>

当您使用增强型流程时，Amazon Cognito 对您的用户会话应用的范围缩小策略会阻止用户会话使用下表中列出的服务以外的任何服务。对于服务子集，仅允许特定操作。


| 类别 | 服务 | 
| --- | --- | 
|  分析  |  Amazon Data Firehose 适用于 Apache Flink 的亚马逊托管服务  | 
|  应用程序集成  |  Amazon Simple Queue Service  | 
| AR 和 VR |  Amazon Sumerian¹  | 
| 业务应用程序 |  Amazon Mobile Analytics Amazon Simple Email Service  | 
| 计算 |  AWS Lambda  | 
| 加密和 PKI |  AWS Key Management Service¹  | 
| 数据库 |  Amazon DynamoDB Amazon SimpleDB  | 
| 前端 Web 和移动 |  AWS AppSync Amazon Location Service Amazon Simple Notification Service Amazon Pinpoint Amazon Location Service  | 
| 游戏开发 |  亚马逊 GameLift 服务器  | 
| 物联网（IoT） |  AWS IoT  | 
| 机器学习 |  Amazon CodeWhisperer Amazon Comprehend Amazon Lex Amazon Machine Learning Amazon Personalize Amazon Polly Amazon Rekognition 亚马逊 SageMaker AI¹ Amazon Textract¹ Amazon Transcribe Amazon Translate  | 
| 管理与治理 |  Amazon CloudWatch Amazon CloudWatch 日志  | 
| 联网和内容分发 |  Amazon API Gateway  | 
| 安全性、身份与合规性 |  Amazon Cognito 用户群体  | 
| 仓储服务 |  Amazon Simple Storage Service  | 

¹ 对于下表 AWS 服务 中的，内联策略授予操作的子集。该表显示了每个服务中的可用操作。


| AWS 服务 | 未经身份验证的增强型流程用户的最大权限 | 
| --- | --- | 
| AWS Key Management Service |  `Encrypt` `Decrypt` `ReEncryptTo` `ReEncryptFrom` `GenerateDataKey` `GenerateDataKeyPair` `GenerateDataKeyPair` `GenerateDataKeyPairWithoutPlaintext` `GenerateDataKeyWithoutPlaintext`  | 
| 亚马逊 SageMaker AI |  `InvokeEndpoint`  | 
| Amazon Textract |  `DetectDocumentText` `AnalyzeDocument`  | 
| Amazon Sumerian |  `View*`  | 
| Amazon Location Service |  `SearchPlaceIndex*` `GetPlace` `CalculateRoute*` `*Geofence` `*Geofences` `*DevicePosition*`  | 

要向此列表 AWS 服务 之外的用户授予访问权限，请在您的身份池中激活**基本（经典）身份验证流程**。如果您的用户发现分配给未经身份验证的用户的 IAM 角色的策略所允许的`NotAuthorizedException`错误，请评估您是否可以将该服务从您的用例中删除。 AWS 服务 如果不能，请切换到基本流程。

### 访客用户的内联会话策略
<a name="access-policies-inline-policy"></a>

Amazon Cognito 首先会在请求 IAM 凭证时应用内联策略。内联会话策略对用户的有效权限进行限制，不能包括对以下列表之外的任何 AWS 服务 的访问权限。您还必须在应用于用户的 IAM 角色的策略 AWS 服务 中向这些角色授予权限。对于代入角色的会话，用户的有效权限是分配给其角色的策略与其会话策略的交集。有关更多信息，请参阅《AWS Identity and Access Management 用户指南》**中的[会话策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)。

Amazon Cognito 将以下内联策略添加到原定设置情况下启用的 AWS 区域 中的用户会话。若要大概了解内联策略和其他会话策略的最终影响，请参阅[未经身份验证的用户可以访问的服务](#access-policies-scope-down-services)。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cloudwatch:*",
                "logs:*",
                "dynamodb:*",
                "kinesis:*",
                "mobileanalytics:*",
                "s3:*",
                "ses:*",
                "sns:*",
                "sqs:*",
                "lambda:*",
                "machinelearning:*",
                "execute-api:*",
                "iot:*",
                "gamelift:*",
                "cognito-identity:*",
                "cognito-idp:*",
                "lex:*",
                "polly:*",
                "comprehend:*",
                "translate:*",
                "transcribe:*",
                "rekognition:*",
                "mobiletargeting:*",
                "firehose:*",
                "appsync:*",
                "personalize:*",
                "sagemaker:InvokeEndpoint",
                "cognito-sync:*",
                "codewhisperer:*",
                "textract:DetectDocumentText",
                "textract:AnalyzeDocument",
                "sdb:*"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
```

------

对于所有其他区域，内联范围缩小策略包括原定设置区域中列出的所有内容，以下 `Action` 语句除外。

```
                "cognito-sync:*",
                "sumerian:View*",
                "codewhisperer:*",
                "textract:DetectDocumentText",
                "textract:AnalyzeDocument",
                "sdb:*"
```

### 访客 AWS 托管会话政策
<a name="access-policies-managed-policy"></a>

Amazon Cognito 还将 AWS 托管策略作为会话策略应用于未经身份验证的访客的增强流量会话。此策略通过策略 `AmazonCognitoUnAuthedIdentitiesSessionPolicy` 限制了未经身份验证的用户的权限范围。

您还必须在附加到未经身份验证的 IAM 角色的策略中授予此权限。对于代入角色会话，用户的有效权限是分配给其角色的 IAM 策略与其会话策略的交集。有关更多信息，请参阅《AWS Identity and Access Management 用户指南》**中的[会话策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)。

有关此 AWS 托管策略和其他会话策略的净效果的概述，请参阅[未经身份验证的用户可以访问的服务](#access-policies-scope-down-services)。

`AmazonCognitoUnAuthedIdentitiesSessionPolicy` 托管式策略具有以下权限。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [{
        "Effect": "Allow",
        "Action": [
            "rum:PutRumEvents",
            "polly:*",
            "comprehend:*",
            "translate:*",
            "transcribe:*",
            "rekognition:*",
            "mobiletargeting:*",
            "firehose:*",
            "personalize:*",
            "sagemaker:InvokeEndpoint",
            "geo:GetMap*",
            "geo:SearchPlaceIndex*",
            "geo:GetPlace",
            "geo:CalculateRoute*",
            "geo:*Geofence",
            "geo:*Geofences",
            "geo:*DevicePosition*",
            "kms:Encrypt",
            "kms:Decrypt",
            "kms:ReEncryptTo",
            "kms:ReEncryptFrom",
            "kms:GenerateDataKey",
            "kms:GenerateDataKeyPair",
            "kms:GenerateDataKeyPairWithoutPlaintext",
            "kms:GenerateDataKeyWithoutPlaintext"
        ],
        "Resource": "*"
    }]
}
```

------

### 访问策略示例
<a name="access-policy-examples"></a>

在本部分中，您可以找到示例 Amazon Cognito 访问策略，这些策略仅向您的用户授予完成特定操作所需的最低权限。您可以在可能的情况下使用策略变量进一步限制给定标识 ID 的权限。例如，使用 \$1\$1cognito-identity.amazonaws.com:sub\$1。有关更多信息，请参阅*AWS 移动博客*上的 [nderstanding Amazon Cognito Authentication Part 3: Roles and Policies](https://aws.amazon.com/blogs/mobile/understanding-amazon-cognito-authentication-part-3-roles-and-policies/)。

**注意**  
作为安全性最佳实践，策略应仅包括用户执行其任务所需的权限。这意味着您应该尽可能始终为对象限定单个身份的访问范围。

**向身份授予对 Amazon S3 中单个对象的读取访问权限**  
以下访问策略向身份授予读取权限，以便从给定的 S3 存储桶中检索单个对象。

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": ["arn:aws:s3:::amzn-s3-demo-bucket/assets/my_picture.jpg"]
    }
  ]
}
```

------

**向身份授予对 Amazon S3 中身份特定路径的读写访问权限**  
以下访问策略通过将前缀映射到 `${cognito-identity.amazonaws.com:sub}` 变量来授予读取和写入权限，以访问 S3 存储桶中的特定前缀“文件夹”。

利用此策略，通过 `${cognito-identity.amazonaws.com:sub}` 插入的身份（例如 `us-east-1:12345678-1234-1234-1234-123456790ab`）将能够在 `arn:aws:s3:::amzn-s3-demo-bucket/us-east-1:12345678-1234-1234-1234-123456790ab` 中获取、放置和列出对象。但是，不会授予身份访问 `arn:aws:s3:::amzn-s3-demo-bucket` 中的其他对象的权限。

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Action": ["s3:ListBucket"],
      "Effect": "Allow",
      "Resource": ["arn:aws:s3:::amzn-s3-demo-bucket"],
      "Condition": {"StringLike": {"s3:prefix": ["${cognito-identity.amazonaws.com:sub}/*"]}}
    },
    {
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": ["arn:aws:s3:::amzn-s3-demo-bucket/${cognito-identity.amazonaws.com:sub}/*"]
    }
  ]
}
```

------

[Amazon S3 访问权限管控](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-grants.html)也实现了类似的访问模式。

**为 Amazon DynamoDB 分配身份细粒度访问权限**  
以下访问策略使用 Amazon Cognito 环境变量，为 DynamoDB 资源提供细粒度访问控制。这些变量按身份 ID 授予对 DynamoDB 中项目的访问权限。有关更多信息，请参阅《Amazon DynamoDB 开发人员指南》**中的[使用 IAM 策略条件实现精细访问控制](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/specifying-conditions.html)。

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:GetItem",
        "dynamodb:BatchGetItem",
        "dynamodb:Query",
        "dynamodb:PutItem",
        "dynamodb:UpdateItem",
        "dynamodb:DeleteItem",
        "dynamodb:BatchWriteItem"
      ],
      "Resource": [
        "arn:aws:dynamodb:us-west-2:123456789012:table/MyTable"
      ],
      "Condition": {
        "ForAllValues:StringEquals": {
          "dynamodb:LeadingKeys":  ["${cognito-identity.amazonaws.com:sub}"]
        }
      }
    }
  ]
}
```

------

**向身份授予调用 Lambda 函数的权限**  
以下访问策略向身份授予调用 Lambda 函数的权限。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
         { 
             "Effect": "Allow",
             "Action": "lambda:InvokeFunction",
             "Resource": [
                 "arn:aws:lambda:us-west-2:123456789012:function:MyFunction"
             ]
         }
     ]
 }
```

------

**向身份授予将记录发布到 Kinesis Data Stream 的权限**  
以下访问策略允许身份将 `PutRecord` 操作与任何 Kinesis Data Streams 结合使用。它可以应用于需要将数据记录添加到账户中所有流的用户。有关更多信息，请参阅《Amazon Kinesis Data Streams 开发人员指南》**中的[使用 IAM 控制对 Amazon Kinesis Data Streams 资源的访问](https://docs.aws.amazon.com/streams/latest/dev/controlling-access.html)。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "kinesis:PutRecord",
            "Resource": [
                "arn:aws:kinesis:us-east-1:111122223333:stream/stream1"
            ]
        }
    ]
}
```

------

**向身份授予访问 Amazon Cognito 同步存储中其数据的权限**  
以下访问策略仅向身份授予访问 Amazon Cognito Sync 存储中其自己数据的权限。

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement":[{
      "Effect":"Allow",
      "Action":"cognito-sync:*",
      "Resource":["arn:aws:cognito-sync:us-east-1:123456789012:identitypool/${cognito-identity.amazonaws.com:aud}/identity/${cognito-identity.amazonaws.com:sub}/*"]
      }]
  }
```

------

## 角色信任和权限
<a name="role-trust-and-permissions"></a>

这些角色的区别在于其信任关系。下面是未经身份验证角色的示例信任策略：

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Federated": "cognito-identity.amazonaws.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "cognito-identity.amazonaws.com:aud": "us-east-1:12345678-corner-cafe-123456790ab"
        },
        "ForAnyValue:StringLike": {
          "cognito-identity.amazonaws.com:amr": "unauthenticated"
        }
      }
    }
  ]
}
```

------

此策略向来自 `cognito-identity.amazonaws.com`（OpenID Connect 令牌的发布者）的联合身份用户授予代入该角色的权限。此外，策略限制令牌的 `aud` (在此示例中为身份池 ID) 匹配身份池。最后，策略指定的由 Amazon Cognito `GetOpenIdToken` API 操作发布的令牌的多值 `amr` 声明的数组成员之一具有值 `unauthenticated`。

当 Amazon Cognito 创建令牌时，它将令牌的 `amr` 设置为 `unauthenticated` 或 `authenticated`。如果 `amr` 是 `authenticated`，则令牌包括身份验证期间使用的所有提供商。这意味着，您可以创建一个角色，它只信任通过 Facebook 登录的用户，这只需将 `amr` 条件更改为如下所示即可：

```
"ForAnyValue:StringLike": {
  "cognito-identity.amazonaws.com:amr": "graph.facebook.com"
}
```

在更改角色的信任关系或尝试跨身份池使用角色时，请务必谨慎。如果您未正确配置角色来信任身份池，则 STS 结果中会出现类似以下内容的异常：

```
AccessDenied -- Not authorized to perform sts:AssumeRoleWithWebIdentity
```

如果您看到此消息，请仔细检查身份池和身份验证类型是否具有正确的角色。

# Amazon Cognito 身份池的安全最佳实践
<a name="identity-pools-security-best-practices"></a>

Amazon Cognito 身份池为您的 AWS 应用程序提供临时证书。 AWS 账户 通常包含应用程序用户所需的资源和私有后端资源。构成 AWS 证书的 IAM 角色和策略可以授予对其中任何资源的访问权限。

身份池配置的主要最佳实践是确保您的应用程序可以在没有过多权限或意外权限的情况下完成工作。为防止安全配置错误，请在要发布到生产环境的每个应用程序启动之前查看这些建议。

**Topics**
+ [IAM 配置最佳实践](#identity-pools-security-best-practices-iam)
+ [身份池配置最佳实践](#identity-pools-security-best-practices-cib)

## IAM 配置最佳实践
<a name="identity-pools-security-best-practices-iam"></a>

当访客或经过身份验证的用户在您的应用程序中启动需要身份池凭证的会话时，您的应用程序会检索 IAM 角色的临时 AWS 凭证。这些凭证可能是默认角色、由身份池配置中的规则选择的角色或应用程序选择的自定义角色的凭证。将权限分配给每个角色后，您的用户就可以访问您的 AWS 资源。

有关常规 IAM 最佳实践的更多信息，请参阅 AWS Identity and Access Management 用户指南[中的 IAM 最佳实践](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)。

### 在 IAM 角色中使用信任策略条件
<a name="identity-pools-security-best-practices-iam-conditions"></a>

IAM 要求身份池的角色至少有一个信任策略条件。例如，此条件可以将角色的作用域设置为仅限经过身份验证的用户。 AWS STS 还要求跨账户基本身份验证请求具有两个特定条件：`cognito-identity.amazonaws.com:aud`和。`cognito-identity.amazonaws.com:amr`作为一项最佳实践，请在信任身份池服务主体 `cognito-identity.amazonaws.com` 的所有 IAM 角色中应用这两个条件。
+ `cognito-identity.amazonaws.com:aud`：身份池令牌中的 *aud* 声明必须与可信身份池 ID 相匹配。
+ `cognito-identity.amazonaws.com:amr`：身份池令牌中的 *amr* 声明必须*经过身份验证*或*未经身份验证*。在这个条件下，您可以将角色的访问权限仅限于未经身份验证的访客，或者仅限于经过身份验证的用户。例如，您可以进一步细化此条件的值，将角色限制为来自特定提供商的用户，例如 `graph.facebook.com`。

以下示例角色信任策略在以下条件下授予对角色的访问权限：

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Federated": "cognito-identity.amazonaws.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "cognito-identity.amazonaws.com:aud": "us-east-1:a1b2c3d4-5678-90ab-cdef-EXAMPLE11111"
        },
        "ForAnyValue:StringLike": {
          "cognito-identity.amazonaws.com:amr": "authenticated"
        }
      }
    }
  ]
}
```

------

**与身份池相关的元素**
+ `"Federated": "cognito-identity.amazonaws.com"`：用户必须来自身份池。
+ `"cognito-identity.amazonaws.com:aud": "us-east-1:a1b2c3d4-5678-90ab-cdef-example11111"`：用户必须来自特定身份池 `us-east-1:a1b2c3d4-5678-90ab-cdef-example11111`。
+ `"cognito-identity.amazonaws.com:amr": "authenticated"`：用户必须已进行身份验证。访客用户无法代入该角色。

### 应用最低权限许可
<a name="identity-pools-security-best-practices-iam-least-privilege"></a>

在使用 IAM 策略为经过身份验证的访问或访客访问设置权限时，请仅授予执行特定任务所需的特定权限或*最低权限*。以下示例 IAM 策略在应用于角色时，授予对 Amazon S3 存储桶中单个映像文件的只读访问权限。

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": ["arn:aws:s3:::mybucket/assets/my_picture.jpg"]
    }
  ]
}
```

------

## 身份池配置最佳实践
<a name="identity-pools-security-best-practices-cib"></a>

身份池为生成 AWS 凭证提供了灵活的选项。当您的应用程序可以使用更安全的方法时，不要在设计上采取捷径。

### 了解访客访问的影响
<a name="identity-pools-security-best-practices-cib-guest"></a>

未经身份验证的访客访问权限允许用户在登录之前从您的 AWS 账户 检索数据。知道您的身份池 ID 的任何人都可以请求未经身份验证的凭证。您的身份池 ID 不是机密信息。激活访客访问 AWS 权限后，所有人均可使用您授予未经身份验证的会话的权限。

妥善的做法是，停用访客访问权限，仅在用户进行身份验证后才获取必需的资源。如果您的应用程序需要在登录前访问资源，请采取以下预防措施。
+ 熟悉[对未经身份验证的角色设置的自动限制](iam-roles.md#access-policies-scope-down-services)。
+ 监控和调整未经身份验证的 IAM 角色的权限，以满足应用程序的特定需求。
+ 授予对特定资源的访问权限。
+ 保护默认未经身份验证的 IAM 角色的信任策略。
+ 只有当您确信自己要将 IAM 角色中的权限授予互联网上的任何人时，才激活访客访问权限。

### 默认使用增强型身份验证
<a name="identity-pools-security-best-practices-cib-enhanced"></a>

通过基本（经典）身份验证，Amazon Cognito 会将选择的 IAM 角色委派给您的应用程序。相比之下，增强型流程使用身份池中的集中式逻辑来确定 IAM 角色。它还通过[范围缩小策略](iam-roles.md#access-policies-scope-down-services)来设置 IAM 权限上限，为未经验证的身份提供了额外的安全性。增强型流程是更安全的选择，开发人员的工作量更少。要了解有关这些选项的更多信息，请参阅[身份池身份验证流程](authentication-flow.md)。

基本流程可以公开用于角色选择和组装 AWS STS API 凭证请求的客户端逻辑。增强型流程通过身份池自动化隐藏了角色选择逻辑和代入角色请求。

配置基本身份验证时，请为您的 IAM 角色及其权限应用 [IAM 最佳实践](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)。

### 安全地使用开发人员提供商
<a name="identity-pools-security-best-practices-cib-developer"></a>

经过开发人员验证的身份是服务器端应用程序身份池的一项特征。身份池开发者身份验证所需的唯一身份验证证据是身份池开发者的 AWS 证书。身份池不会对您在此身份验证流程中提供的开发人员-提供商标识符的有效性施加任何限制。

作为一项最佳实践，仅在以下条件下实施开发人员提供商：
+ 为了确保使用经过开发人员验证的凭证的责任能够追溯，请将您的开发人员提供商名称和标识符设计为可指明身份验证来源。例如：`"Logins" : {"MyCorp provider" : "[provider application ID]"}`。
+ 避免使用长期用户凭证。将服务器端客户端配置为使用服务相关角色（如 [EC2 实例配置文件](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html)和 [Lambda 执行角色](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)）请求身份。
+ 避免在同一个身份池中混用内部和外部信任源。在单独的身份池中添加开发人员提供者和单点登录（SSO）提供者。

# 将属性用于访问控制
<a name="attributes-for-access-control"></a>

访问控制属性是基于属性的访问权限控制（ABAC）的 Amazon Cognito 身份池实现。您可以通过基于用户属性的 Amazon Cognito 身份池使用 IAM 策略来控制对 AWS 资源的访问。可以从社交和企业身份提供商那里获得这些属性。您可以将提供商的访问权限和 ID 令牌或 SAML 断言中的属性映射到可在 IAM 权限策略中引用的标签。

您可以选择默认映射或在 Amazon Cognito 身份池中创建自己的自定义映射。默认映射让您可以根据一组固定的用户属性编写 IAM 策略。自定义映射允许您选择 IAM 权限策略中引用的一组自定义用户属性。Amazon Cognito 控制台中的 **Attribute names (属性名称)** 已映射到 **Tag key for principal (委托人的标签密钥)**，这些是 IAM 权限策略中引用的标签。

例如，假设您拥有一个具有免费和付费会员资格的媒体流式传输服务。您可以将媒体文件存储在 Amazon S3 中，并使用免费或高级标签对其贴标签。您可以将属性用于访问控制，以允许访问基于用户会员级别（这是用户配置文件的一部分）的免费和付费内容。您可以将成员资格属性映射到委托人的标签密钥，以传递给 IAM 权限策略。通过这种方式，您可以创建单个权限策略，并根据会员级别的值和内容文件上的标签有条件地允许对高级内容的访问。

**Topics**
+ [使用属性对 Amazon Cognito 身份池进行访问控制](#using-afac-with-cognito-identity-pools)
+ [示例：将属性用于访问控制策略](#using-attributes-for-access-control-policy-example)
+ [关闭访问控制属性（控制台）](#disable-afac)
+ [默认提供商映射](#provider-mappings)

使用属性来控制访问有若干优势：
+ 使用属性进行访问控制时，权限管理会更高效。您可以创建使用用户属性的基本权限策略，而不必为不同的任务功能创建多个策略。
+ 不管您何时为应用程序添加或删除资源或用户，都无需更新策略。权限策略只向具有匹配用户属性的用户授予访问权限。例如，您可能需要根据用户的任务标题控制对某些 S3 存储桶的访问权限。在这种情况下，您可以创建权限策略，以便仅允许定义的任务标题中的用户访问这些文件。有关更多信息，请参阅 [IAM 教程：将 SAML 会话标签用于 ABAC](https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_abac-saml.html)。
+ 属性可以作为委托人标签传递给策略，该策略基于这些属性的值允许或拒绝权限。

## 使用属性对 Amazon Cognito 身份池进行访问控制
<a name="using-afac-with-cognito-identity-pools"></a>

使用属性进行访问控制之前，请确保满足以下先决条件：
+ [一个 AWS 账户](https://docs.aws.amazon.com/cognito/latest/developerguide/getting-started-with-identity-pools.html#aws-sign-up-identity-pools)
+ [用户池](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-as-user-directory.html)
+ [身份池](https://docs.aws.amazon.com/cognito/latest/developerguide/getting-started-with-identity-pools.html#create-identity-pools)
+ [设置 SDK](getting-started-with-identity-pools.md#install-the-mobile-or-javascript-sdk)
+ [已集成身份提供商](https://docs.aws.amazon.com/cognito/latest/developerguide/getting-started-with-identity-pools.html##integrate-the-identity-providers)
+ [凭据](https://docs.aws.amazon.com/cognito/latest/developerguide/getting-started-with-identity-pools.html#get-credentials)

要使用属性进行访问控制，您设置为数据来源的**声明**将设置您选择的**标签键**的值。Amazon Cognito 会将标签键和值应用于您的用户会话。您的 IAM policy 可以根据 `${aws:PrincipalTag/tagkey}` 条件评估用户的访问权限。IAM 会根据策略评估用户标签的值。

您必须准备要将其凭证传递给用户的 IAM 角色。这些角色的信任策略必须允许 Amazon Cognito 为您的用户代入该角色。对于用于访问控制的属性，您还必须允许 Amazon Cognito 将主体标签应用于用户的临时会话。授予通过操作代入角色的权限[AssumeRoleWithWebIdentity](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html)。授予使用[仅限权限操作](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awssecuritytokenservice.html#awssecuritytokenservice-actions-as-permissions) `sts:TagSession` 标记用户会话的权限。有关更多信息，请参阅《AWS Identity and Access Management 用户指南》**中的[在 AWS Security Token Service中传递会话标签](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)。有关向 Amazon Cognito 服务主体 `cognito-identity.amazonaws.com` 授予 `sts:AssumeRoleWithWebIdentity` 和 `sts:TagSession` 权限的示例信任策略，请参阅[示例：将属性用于访问控制策略](#using-attributes-for-access-control-policy-example)。

**在控制台中配置访问控制属性**

1. 登录 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)并选择**身份池**。选择身份池。

1. 选择**用户访问**选项卡。

1. 找到**身份提供者**。选择要编辑的身份提供者。如果要添加新的 IdP，请选择**添加身份提供者**。

1. 要更改 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时分配的主体标签，请在**访问控制属性**中选择**编辑**。

   1. 如果不应用主体标签，请选择**非活动**。

   1. 要基于 `sub` 和 `aud` 声明应用主体标签，请选择**使用原定设置映射**。

   1. 要为主体标签创建自己的自定义属性模式，请选择**使用自定义映射**。然后，对于您要在标签中表示的每个**声明**，输入要从该声明中获取的**标签键**。

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

## 示例：将属性用于访问控制策略
<a name="using-attributes-for-access-control-policy-example"></a>

考虑这样一种场景：某公司法律部门的员工需要列出存储桶中属于其部门并按其安全级别分类的所有文件。假定此员工从身份提供商获得的令牌包含以下陈述。

**声明**

```
            { .
              .
            "sub" : "57e7b692-4f66-480d-98b8-45a6729b4c88",
            "department" : "legal",
            "clearance" : "confidential",
             .
             .
            }
```

这些属性可以映射到标签，并在 IAM 权限策略中作为委托人标签引用。现在，您可以通过更改身份提供商端的用户配置文件来管理访问权限。或者，您可以使用名称或标签来更改资源端的属性，而无需更改策略本身。

以下权限策略有两个作用：
+ 允许列表访问以与用户部门名称匹配的前缀结尾的所有 S3 桶。
+ 允许对这些存储桶中的文件进行读取访问，只要文件上的清理标签与用户的清理属性匹配。

**权限策略**

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

****  

```
   {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:List*",
            "Resource": "arn:aws:s3:::*-${aws:PrincipalTag/department}"
        },
        {
            "Effect": "Allow",
            "Action": "s3:GetObject*",
            "Resource": "arn:aws:s3:::*-${aws:PrincipalTag/department}/*",
            "Condition": {
                "StringEquals": {
                    "s3:ExistingObjectTag/clearance": "${aws:PrincipalTag/clearance}"
                }
            }
        }
    ]
}
```

------

信任策略决定谁可担任此角色。信任关系策略允许使用 `sts:AssumeRoleWithWebIdentity` 和 `sts:TagSession` 来允许访问。它添加了一部分条件，以将策略限制为您创建的身份池，并确保该策略适用于经身份验证的角色。

**信任策略**

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "cognito-identity.amazonaws.com"
      },
      "Action": [
        "sts:AssumeRoleWithWebIdentity",
        "sts:TagSession"
      ],
      "Condition": {
        "StringEquals": {
          "cognito-identity.amazonaws.com:aud": "IDENTITY-POOL-ID"
        },
        "ForAnyValue:StringLike": {
          "cognito-identity.amazonaws.com:amr": "authenticated"
        }
      }
    }
  ]
}
```

------

## 关闭访问控制属性（控制台）
<a name="disable-afac"></a>

按照以下操作步骤来停用访问控制属性。

**在控制台中停用访问控制属性**

1. 登录 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)并选择**身份池**。选择身份池。

1. 选择**用户访问**选项卡。

1. 找到**身份提供者**。选择要编辑的身份提供者。

1. 在**访问控制属性**中选择**编辑**。

1. 如果不应用主体标签，请选择**非活动**。

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

## 默认提供商映射
<a name="provider-mappings"></a>

下表提供 Amazon Cognito 支持的身份验证提供商的默认映射信息。


| Provider | 令牌类型 | 委托人标签值 | 示例 | 
| --- | --- | --- | --- | 
|  Amazon Cognito 用户池  |  ID 令牌  |  aud（客户端 ID）和 sub（用户 ID）  |  "6jk8ltokc7ac9es6jrtg9q572f"，"57e7b692-4f66-480d-98b8-45a6729b4c88"  | 
|  Facebook  |  访问令牌  |  aud（app\$1id），sub（user\$1id）  |  “492844718097981”，“112177216992379”  | 
|  Google  |  ID 令牌  |  aud（客户端 ID）和 sub（用户 ID）  |  “620493171733-eebk7c0hcp5lj3e1tlqp1gntt3k0rncv.apps.googleusercontent.com”，“109220063452404746097”  | 
|  SAML  |  断言  |  “http://schemas.xmlsoap。 org/ws/2005/05/identity/claims/nameidentifier" , "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name”   |  "auth0\$15e28d196f8f55a0eaaa95de3"，"user123@gmail.com"  | 
|  Apple  |  ID 令牌  |  aud（客户端 ID）和 sub（用户 ID）  |  “com.amazonaws.ec2-54-80-172-243.compute-1.client”，“001968.a6ca34e9c1e742458a26cf8005854be9.0733”  | 
|  Amazon  |  访问令牌  |  aud（Amzn Dev Ac 上的客户端 ID），user\$1id（用户 ID）  |  “amzn1.application-oa2-client.9d70d9382d3446108aaee3dd763a0fa6”，“amzn1.account。 AGHNIFJQMFSBG3G6 XCPVB35 ORQAA”  | 
|  标准 OIDC 提供商  |  ID 令牌和访问令牌  |  aud（作为 client\$1id）和 sub（作为用户 ID）  |  “620493171733-eebk7c0hcp5lj3e1tlqp1gntt3k0rncv.apps.googleusercontent.com”，“109220063452404746097”  | 
|  Twitter  |  访问令牌  |  aud（应用程序 ID；应用程序密钥），sub（用户 ID）  |  “DfwifTtKEX1Fi IBRn OTl R0CFK；xgj5xb8xir Xg w7fxmwc fvnok9 1y5z1，“1269003884292222976IVCPj” LIdk JJr gwZkLexo  | 
|  DevAuth  |  Map  |  不适用  |  "tag1", "tag2"  | 

**注意**  
**Tag Key for Principal (委托人的标签密钥)** 和 **Attribute (属性)** 名称的默认属性映射选项会自动填充。您无法更改默认映射。

# 使用基于角色的访问控制
<a name="role-based-access-control"></a>

Amazon Cognito 身份池为您的经过身份验证的用户分配一组临时的、权限有限的凭证，以访问您的资源。 AWS 每个用户的权限通过您创建的 [IAM 角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html)进行控制。您可以定义规则，以便基于用户 ID 令牌中的声明为每个用户选择角色。您可以为经过身份验证的用户定义一个默认角色。您也可以为未经身份验证的来宾用户定义一个具有有限权限的单独的 IAM 角色。

## 为角色映射创建角色
<a name="creating-roles-for-role-mapping"></a>

请务必为每个角色添加适当的信任策略，这样只能由 Amazon Cognito 针对您的身份池中经过身份验证的用户担任。下面是此类信任策略的示例：

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Federated": "cognito-identity.amazonaws.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "cognito-identity.amazonaws.com:aud": "us-east-1:12345678-corner-cafe-123456790ab"
        },
        "ForAnyValue:StringLike": {
          "cognito-identity.amazonaws.com:amr": "authenticated"
        }
      }
    }
  ]
}
```

------

此策略允许来自 `cognito-identity.amazonaws.com` (OpenID Connect 令牌的发布者) 的联合身份用户担任该角色。此外，策略限制令牌的 `aud` (在此示例中为身份池 ID) 匹配身份池。最后，策略指定的由 Amazon Cognito `GetOpenIdToken` API 操作发布的令牌的多值 `amr` 声明的数组成员之一具有值 `authenticated`。

## 授予传递角色权限
<a name="granting-pass-role-permission"></a>

要允许用户为角色设置超过该用户在身份池上的现有权限的权限，您需授予用户 `iam:PassRole` 权限以将角色传递给 `set-identity-pool-roles` API。例如，如果用户无法写入 Amazon S3，但用户在身份池上设置的 IAM 角色可向 Amazon S3 授予写入权限，则用户只能在已向该角色授予 `iam:PassRole` 权限的情况下设置该角色。以下示例策略介绍了如何提供 `iam:PassRole` 权限。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "Stmt1",
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::123456789012:role/myS3WriteAccessRole"
            ]
        }
    ]
}
```

------

在此策略示例中，将 `iam:PassRole` 权限授予了角色 `myS3WriteAccessRole`。使用角色的 Amazon Resource Name（ARN）指定该角色。您必须将此策略附加到您的用户。有关更多信息，请参阅[使用管理的策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-using.html)。

**注意**  
Lambda 函数使用基于资源的策略，该策略直接附加至 Lambda 函数本身。创建调用 Lambda 函数的规则时，您未传递角色，因此创建规则的用户无需 `iam:PassRole` 权限。有关 Lambda 函数授权的更多信息，请参阅[管理权限：使用 Lambda 函数策略](https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html#intro-permission-model-access-policy)。

## 使用令牌向用户分配角色
<a name="using-tokens-to-assign-roles-to-users"></a>

对于通过 Amazon Cognito 用户池登录的用户，角色可在用户池分配的 ID 令牌中进行传递。角色将显示在 ID 令牌的以下声明中：
+ `cognito:preferred_role` 声明是角色 ARN。
+ `cognito:roles`声明是一个以逗号分隔的字符串，其中包含一组允许的角色。 ARNs

声明按如下方式设置：
+ `cognito:preferred_role` 声明设置为组中具有最大 (最小) `Precedence` 值的角色。如果只有一个允许的角色，则 `cognito:preferred_role` 设置为该角色。如果存在多个角色且没有一个角色具有最高优先级，则此声明未设置。
+ 如果至少存在一个角色，则 `cognito:roles` 声明已设置。

使用令牌分配角色时，如果存在多个可向用户分配的角色，Amazon Cognito 身份池（联合身份）将按以下方式选择角色：
+ 如果[GetCredentialsForIdentity](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetCredentialsForIdentity.html)`CustomRoleArn`参数已设置并且与`cognito:roles`声明中的角色匹配，则使用该参数。如果此参数与 `cognito:roles` 中的角色不匹配，则拒绝访问。
+ 如果 `cognito:preferred_role` 声明已设置，请使用它。
+ 如果未设置`cognito:preferred_role`声明，则`cognito:roles`声明已设置，`CustomRoleArn`且未在调用中指定`GetCredentialsForIdentity`，则使用控制台中的**角色解析**设置或`AmbiguousRoleResolution`字段（在 [SetIdentityPoolRoles](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_SetIdentityPoolRoles.html)API 的`RoleMappings`参数中）来确定要分配的角色。

## 使用基于规则的映射向用户分配角色
<a name="using-rules-to-assign-roles-to-users"></a>

规则允许您将身份提供商令牌的声明映射到 IAM 角色。

每个规则指定一个令牌声明（例如 Amazon Cognito 用户池的 ID 令牌中的用户属性）、匹配类型、值和 IAM 角色。匹配类型可以是 `Equals`、`NotEqual`、`StartsWith` 或 `Contains`。如果用户拥有声明的匹配值，则该用户可在获取凭证后担任该角色。例如，您可以创建一个规则，为 `custom:dept` 自定义属性值为 `Sales` 的用户分配一个特定的 IAM 角色。

**注意**  
在规则设置中，自定义属性需要使用 `custom:` 前缀，以便将它们与标准属性区分开来。

规则按顺序进行评估，并使用第一条匹配规则的 IAM 角色，除非指定 `CustomRoleArn` 以覆盖顺序。有关 Amazon Cognito 用户池中用户属性的更多信息，请参阅[使用用户属性](user-pool-settings-attributes.md)。

您可以在身份池（联合身份）控制台中为身份验证提供商设置多条规则。按顺序应用规则。您可以拖动规则以更改其顺序。第一条匹配规则优先。如果匹配类型为 `NotEqual` 且声明不存在，则不会对规则进行评估。如果没有规则匹配，则**角色解析**设置应用到**使用经过身份验证的原定设置角色**或**拒绝请求**。

在 API 和 CLI 中，您可以指定在[RoleMapping](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_RoleMapping.html)类型字段中没有匹配规则时要分配的角色，该`AmbiguousRoleResolution`字段在 [SetIdentityPoolRoles](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_SetIdentityPoolRoles.html)API 的`RoleMappings`参数中指定。

要在 Amazon Cognito 控制台中向身份提供者添加基于规则的映射，请添加或更新 IdP，然后选择**角色选择**下面的**使用规则选择角色**。在这里，您可以添加规则，将提供者声明映射到 IAM 角色。

您可以使用类型的`RulesConfiguration`字段在 AWS CLI 或 API 中为身份提供者设置基于规则的[RoleMapping](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_RoleMapping.html)映射。您可以在 [SetIdentityPoolRoles](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_SetIdentityPoolRoles.html)API 的`RoleMappings`参数中指定此字段。

例如，以下 AWS CLI 命令添加了一条规则，该规则将角色分配`arn:aws:iam::123456789012:role/Sacramento_team_S3_admin`给萨克拉曼多所在地经过 OIDC IdP 身份验证的用户：`arn:aws:iam::123456789012:oidc-provider/myOIDCIdP`

```
aws cognito-identity set-identity-pool-roles --region us-east-1 --cli-input-json file://role-mapping.json
```

**`role-mapping.json` 的内容**：

```
{
    "IdentityPoolId": "us-east-1:12345678-corner-cafe-123456790ab",
    "Roles": {
        "authenticated": "arn:aws:iam::123456789012:role/myS3WriteAccessRole",
        "unauthenticated": "arn:aws:iam::123456789012:role/myS3ReadAccessRole"
    },
    "RoleMappings": {
        "arn:aws:iam::123456789012:oidc-provider/myOIDCIdP": {
            "Type": "Rules",
            "AmbiguousRoleResolution": "AuthenticatedRole",
            "RulesConfiguration": {
                "Rules": [
                    {
                        "Claim": "locale",
                        "MatchType": "Equals",
                        "Value": "Sacramento",
                        "RoleARN": "arn:aws:iam::123456789012:role/Sacramento_team_S3_admin"
                    }
                ]
            }
        }
    }
}
```

对于每个用户池或为某个身份池配置的其他身份验证提供商，您可以创建最多 25 条规则。此限制不可调整。有关更多信息，请参阅 [Amazon Cognito 中的配额](https://docs.aws.amazon.com/cognito/latest/developerguide/limits.html)。

## 基于规则的映射中使用的令牌声明
<a name="token-claims-for-role-based-access-control"></a>

**Amazon Cognito**

Amazon Cognito ID 令牌以 JSON Web Token（JWT）表示。令牌包含有关经过身份验证的用户的身份声明，例如 `name`、`family_name` 和 `phone_number`。有关标准声明的更多信息，请参阅 [OpenID Connect 规范](http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims)。除了标准声明之外，以下是特定于 Amazon Cognito 的额外声明：
+ `cognito:groups`
+ `cognito:roles`
+ `cognito:preferred_role`

**Amazon**

以下声明以及这些声明可能的值可与 Login with Amazon 配合使用：
+ `iss`：www.amazon.com
+ `aud`：应用程序 ID
+ `sub`：Login with Amazon 令牌中的 `sub`

**Facebook**

以下声明以及这些声明可能的值可与 Facebook 配合使用：
+ `iss`：graph.facebook.com
+ `aud`：应用程序 ID
+ `sub`：Facebook 令牌中的 `sub`

**Google**

Google 令牌包含 [OpenID Connect 规范](http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims)中的标准声明。OpenID 令牌中的所有声明均可用于基于规则的映射。请参阅 Google 的 [OpenID Connect](https://developers.google.com/identity/protocols/OpenIDConnect) 网站，了解 Google 令牌中包含的声明。

**Apple**

Apple 令牌包含 [OpenID Connect 规范](http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims)中的标准声明。请参阅 Apple 文档中的[使用 Sign in with Apple 对用户进行身份验证](https://developer.apple.com/documentation/signinwithapple/authenticating-users-with-sign-in-with-apple)，详细了解有关 Apple 令牌提供的声明。Apple 的令牌并不总是包含 `email`。

**OpenID**

OpenID 令牌中的所有声明均可用于基于规则的映射。有关标准声明的更多信息，请参阅 [OpenID Connect 规范](http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims)。请参阅您的 OpenID 提供商文档，了解其中包含的任何额外声明。

**SAML**

根据收到的 SAML 断言分析声明。SAML 断言中包含的所有声明均可在基于规则的映射中使用。

## 基于角色的访问控制的最佳实践
<a name="best-practices-for-role-based-access-control"></a>

**重要**  
如果最终用户可修改您映射到角色的声明，则任何最终用户均可担任您的角色并相应地设置策略。仅将无法由最终用户直接设置的声明映射到具有提升的权限的角色。在 Amazon Cognito 用户池中，您可以为每个用户属性设置每个应用程序的读取和写入权限。

**重要**  
如果您在 Amazon Cognito 用户池中为组设置角色，这些角色将通过用户的 ID 令牌进行传递。要使用这些角色，您还必须为身份池中选择的通过身份验证的角色设置 **Choose role from token**（使用令牌选择角色）。  
您可以使用控制台中的**角色解析**设置和 [SetIdentityPoolRoles](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_SetIdentityPoolRoles.html)API 的`RoleMappings`参数来指定无法通过令牌确定正确的角色时的默认行为。

# 获取凭证
<a name="getting-credentials"></a>

您可以使用 Amazon Cognito 为您的应用程序提供临时的、权限有限的证书，以便您的用户可以访问资源。 AWS 本部分介绍如何获取凭证以及如何从身份池检索 Amazon Cognito 身份。

Amazon Cognito 同时支持经过身份验证和未经身份验证的身份。未经身份验证的用户的身份未经过验证，因此，该角色很适合您的应用程序的来宾用户或用户身份验证与否无关紧要的情形。经过身份验证的用户可以通过第三方身份提供商或证实其身份的用户池登录到您的应用程序。确保您的资源的权限范围适当，让未经身份验证的用户无权访问这些资源。

Amazon Cognito 身份并不是凭证。使用 AWS Security Token Service (AWS STS) 中的 Web 联合身份验证支持将它们交换为凭证。建议使用 `AWS.CognitoIdentityCredentials` 来为您的应用程序用户获得 AWS 凭证。然后使用将凭证对象中的身份交换为证书 AWS STS。

**注意**  
如果您的身份池是在 2015 年 2 月前创建的，则必须将角色与身份池重新关联，以便在没有角色作为参数的情况下使用 `AWS.CognitoIdentityCredentials` 构造函数。为此，请打开 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)，选择 **Manage identity pools**（管理身份池）、选择您的身份池，然后选择 **Edit identity Pool**（编辑身份池），指定您的经过身份验证的角色和未经身份验证的角色，然后保存更改。

Web 身份凭证提供者是中默认凭证提供者链的一部分。 AWS SDKs要在本地`config`文件中为 AWS SDK 或设置身份池令牌 AWS CLI，请添加`web_identity_token_file`个人资料条目。请参阅《工具参考指南》 AWS SDKs 和《工具参考指南》中的代入[角色凭证提供者](https://docs.aws.amazon.com/sdkref/latest/guide/feature-assume-role-credentials.html)。

要详细了解如何在 SDK 中填充 Web 身份凭证，请参阅《SDK 开发人员指南》。为了获得最佳效果，请使用内置的身份池集成开始您的项目 AWS Amplify。

**AWS 用于通过身份池获取和设置凭证的 SDK 资源**
+ 《Amplify 开发人员中心》的[身份池联合身份验证](https://docs.amplify.aws/lib/auth/advanced/q/platform/android/#identity-pool-federation)（Android）
+ 《Amplify 开发人员中心》的[身份池联合身份验证](https://docs.amplify.aws/lib/auth/advanced/q/platform/ios/#identity-pool-federation)（iOS）
+ 开发者指南中@@ [使用亚马逊 Cognito 身份对用户进行 适用于 JavaScript 的 AWS SDK 身份验证](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/loading-browser-credentials-cognito.html)
+ 开发者指南中的@@ [亚马逊 Cognito 凭证提供商](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/cognito-creds-provider.html) 适用于 .NET 的 AWS SDK 
+ 在《 适用于 Go 的 AWS SDK 开发者指南》中@@ [以编程方式指定凭证](https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/#specify-credentials-programmatically)
+ 在《 AWS SDK for Java 2.x 开发人员指南[》的代码中提供临时证书](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/credentials-explicit.html)
+ [assumeRoleWithWebIdentityCredentialProvider](https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials_provider.html#assume-role-with-web-identity-provider) 适用于 PHP 的 AWS SDK 开发者指南中的提供商
+  适用于 Python (Boto3) 的 AWS SDK 文档中的[代入 Web 身份提供者的角色](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html#assume-role-with-web-identity-provider)
+ 在 适用于 Rust 的 AWS SDK 开发者指南中@@ [指定您的凭证和默认区域](https://docs.aws.amazon.com/sdk-for-rust/latest/dg/credentials.html)

以下各节提供了一些旧版的示例代码 AWS SDKs。

## Android
<a name="getting-credentials-1.android"></a>

您可以使用 Amazon Cognito 为您的应用程序提供临时的、权限有限的证书，以便您的用户可以访问资源。 AWS Amazon Cognito 同时支持经过身份验证和未经身份验证的身份。要为您的应用程序提供 AWS 凭证，请按照以下步骤操作。

要在安卓应用程序中使用 Amazon Cognito 身份池，请进行设置。 AWS Amplify有关更多信息，请参阅《Amplify 开发中心》**中的[身份验证](https://docs.amplify.aws/lib/auth/getting-started/q/platform/android/)。

**检索 Amazon Cognito 身份**

如果您允许未经身份验证的用户，则可以立即检索终端用户的唯一 Amazon Cognito 标识符（身份 ID）。如果您正在对用户进行身份验证，则可以在设置完凭证提供程序中的登录令牌后检索身份 ID：

```
String identityId = credentialsProvider.getIdentityId();
Log.d("LogTag", "my ID is " + identityId);
```

**注意**  
 请勿在应用程序的主线程中调用 `getIdentityId()`、`refresh()` 或 `getCredentials()`。从 Android 3.0（API 级别 11）开始，[NetworkOnMainThreadException](https://developer.android.com/reference/android/os/NetworkOnMainThreadException.html)如果您在主应用程序线程 I/O 上执行网络，您的应用程序将自动失败并抛出。您必须使用 `AsyncTask` 将您的代码移至后台线程。有关更多信息，请参阅 [Android 文档](https://developer.android.com/training/basics/network-ops/connecting.html#AsyncTask)。您也可以调用 `getCachedIdentityId()` 以检索 ID，但前提是已缓存在本地。否则，该方法将返回 null 值。

## iOS - Objective-C
<a name="getting-credentials-1.ios-objc"></a>

您可以使用 Amazon Cognito 为您的应用程序提供临时的、权限有限的证书，以便您的用户可以访问资源。 AWS Amazon Cognito 身份池同时支持经过身份验证和未经身份验证的身份。要为您的应用程序提供 AWS 凭证，请完成以下步骤。

要在 iOS 应用程序中使用 Amazon Cognito 身份池，请进行设置。 AWS Amplify有关更多信息，请参阅《Amplify 开发中心》**中的 [Swift 身份验证](https://docs.amplify.aws/lib/auth/getting-started/q/platform/ios/)和 [Flutter 身份验证](https://docs.amplify.aws/lib/auth/getting-started/q/platform/flutter/)。

**检索 Amazon Cognito 身份**

如果您允许未经身份验证的用户或者已设置完凭证提供程序中的登录令牌（如果您正在对用户进行身份验证），则可以立即检索终端用户的唯一 Amazon Cognito 标识符（身份 ID）：

```
// Retrieve your Amazon Cognito ID
[[credentialsProvider getIdentityId] continueWithBlock:^id(AWSTask *task) {
    if (task.error) {
        NSLog(@"Error: %@", task.error);
    }
    else {
        // the task result will contain the identity id
        NSString *cognitoId = task.result;
    }
    return nil;
}];
```

**注意**  
 `getIdentityId` 为异步调用。如果您已在提供程序上设置身份 ID，则可以调用 `credentialsProvider.identityId` 以检索已缓存在本地的身份。但是，如果您未在提供程序上设置身份 ID，则调用 `credentialsProvider.identityId` 将返回 `nil`。有关更多信息，请参阅 [Amplify iOS SDK 参考](https://github.com/aws-amplify/aws-sdk-ios)。

## iOS - Swift
<a name="getting-credentials-1.ios-swift"></a>

您可以使用 Amazon Cognito 为您的应用程序提供临时的、有限权限的证书，以便您的用户可以访问资源。 AWS Amazon Cognito 同时支持经过身份验证和未经身份验证的身份。要为您的应用程序提供 AWS 凭证，请按照以下步骤操作。

要在 iOS 应用程序中使用 Amazon Cognito 身份池，请进行设置。 AWS Amplify有关更多信息，请参阅《Amplify 开发中心》**中的 [Swift 身份验证](https://docs.amplify.aws/lib/auth/getting-started/q/platform/ios/)。

**检索 Amazon Cognito 身份**

如果您允许未经身份验证的用户或者已设置完凭证提供程序中的登录令牌（如果您正在对用户进行身份验证），则可以立即检索终端用户的唯一 Amazon Cognito 标识符（身份 ID）：

```
// Retrieve your Amazon Cognito ID
credentialsProvider.getIdentityId().continueWith(block: { (task) -> AnyObject? in
    if (task.error != nil) {
        print("Error: " + task.error!.localizedDescription)
    }
    else {
        // the task result will contain the identity id
        let cognitoId = task.result!
        print("Cognito id: \(cognitoId)")
    }
    return task;
})
```

**注意**  
 `getIdentityId` 为异步调用。如果您已在提供程序上设置身份 ID，则可以调用 `credentialsProvider.identityId` 以检索已缓存在本地的身份。但是，如果您未在提供程序上设置身份 ID，则调用 `credentialsProvider.identityId` 将返回 `nil`。有关更多信息，请参阅 [Amplify iOS SDK 参考](https://github.com/aws-amplify/aws-sdk-ios)。

## JavaScript
<a name="getting-credentials-1.javascript"></a>

如果您尚未创建身份池，则在使用 `AWS.CognitoIdentityCredentials` 之前，先在 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito)中创建一个身份池。

通过您的身份提供商配置身份池后，您可以使用 `AWS.CognitoIdentityCredentials` 验证用户身份。要将应用程序凭证配置为使用 `AWS.CognitoIdentityCredentials`，则为 `credentials` 或基于每个服务配置设置 `AWS.Config` 属性。以下示例使用 `AWS.Config`：

```
// Set the region where your identity pool exists (us-east-1, eu-west-1)
AWS.config.region = 'us-east-1';

// Configure the credentials provider to use your identity pool
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
    IdentityPoolId: 'IDENTITY_POOL_ID',
    Logins: { // optional tokens, used for authenticated login
        'graph.facebook.com': 'FBTOKEN',
        'www.amazon.com': 'AMAZONTOKEN',
        'accounts.google.com': 'GOOGLETOKEN',
        'appleid.apple.com': 'APPLETOKEN'
    }
});

// Make the call to obtain credentials
AWS.config.credentials.get(function(){

    // Credentials will be available when this function is called.
    var accessKeyId = AWS.config.credentials.accessKeyId;
    var secretAccessKey = AWS.config.credentials.secretAccessKey;
    var sessionToken = AWS.config.credentials.sessionToken;

});
```

可选的 `Logins` 属性是身份提供商名称到这些提供商身份令牌的映射。您如何从身份提供商获得令牌的方式取决于您使用的提供商。例如，如果 Facebook 是您的身份提供商之一，则您可以使用来自 [Facebook 软件开发工具包](https://developers.facebook.com/docs/facebook-login/web)的 `FB.login` 函数获取身份提供商令牌：

```
FB.login(function (response) {
    if (response.authResponse) { // logged in
        AWS.config.credentials = new AWS.CognitoIdentityCredentials({
          IdentityPoolId: 'us-east-1:1699ebc0-7900-4099-b910-2df94f52a030',
          Logins: {
            'graph.facebook.com': response.authResponse.accessToken
          }
        });

        console.log('You are now logged in.');
    } else {
        console.log('There was a problem logging you in.');
    }
});
```

**检索 Amazon Cognito 身份**

如果您允许未经身份验证的用户或者已设置完凭证提供程序中的登录令牌（如果您正在对用户进行身份验证），则可以立即检索终端用户的唯一 Amazon Cognito 标识符（身份 ID）：

```
var identityId = AWS.config.credentials.identityId;
```

## Unity
<a name="getting-credentials-1.unity"></a>

 您可以使用 Amazon Cognito 为您的应用程序提供临时的、权限有限的证书，以便您的用户可以访问资源。 AWS Amazon Cognito 同时支持经过身份验证和未经身份验证的身份。要为您的应用程序提供 AWS 凭证，请按照以下步骤操作。

[适用于 Unity 的AWS SDK](https://docs.aws.amazon.com/mobile/sdkforunity/developerguide/what-is-unity-plugin.html) 现在是 [适用于 .NET 的 SDK](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/welcome.html) 的一部分。要开始使用中的亚马逊 Cognito 适用于 .NET 的 SDK，请参阅开发者指南中的[亚马逊 Cognito 凭证](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/cognito-creds-provider.html)提供商。 适用于 .NET 的 AWS SDK 或者，请参阅 [Amplify 开发者中心](https://docs.amplify.aws/)，了解用于构建应用程序的选项。 AWS Amplify

**检索 Amazon Cognito 身份**

 如果您允许未经身份验证的用户或者已设置完凭证提供程序中的登录令牌（如果您正在对用户进行身份验证），则可以立即检索终端用户的唯一 Amazon Cognito 标识符（身份 ID）：

```
credentials.GetIdentityIdAsync(delegate(AmazonCognitoIdentityResult<string> result) {
    if (result.Exception != null) {
        //Exception!
    }
    string identityId = result.Response;
});
```

## Xamarin
<a name="getting-credentials-1.xamarin"></a>

您可以使用 Amazon Cognito 为您的应用程序提供临时的、有限权限的证书，以便您的用户可以访问资源。 AWS Amazon Cognito 同时支持经过身份验证和未经身份验证的身份。要为您的应用程序提供 AWS 凭证，请按照以下步骤操作。

[适用于 Xamarin 的AWS SDK](https://docs.aws.amazon.com/mobile/sdkforxamarin/developerguide/Welcome.html) 现在是 [适用于 .NET 的 SDK](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/welcome.html) 的一部分。要开始使用中的亚马逊 Cognito 适用于 .NET 的 SDK，请参阅开发者指南中的[亚马逊 Cognito 凭证](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/cognito-creds-provider.html)提供商。 适用于 .NET 的 AWS SDK 或者，请参阅 [Amplify 开发者中心](https://docs.amplify.aws/)，了解用于构建应用程序的选项。 AWS Amplify

**注意**  
 **注意**：如果您在 2015 年 2 月之前创建了身份池，您必须将您的角色与身份池重新关联，才能在没有角色作为参数的情况下使用此构造函数。为此，请打开 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)，选择 **Manage identity pools**（管理身份池）、选择您的身份池，然后选择 **Edit identity Pool**（编辑身份池），指定您的经过身份验证的角色和未经身份验证的角色，然后保存更改。

**检索 Amazon Cognito 身份**

 如果您允许未经身份验证的用户或者已设置完凭证提供程序中的登录令牌（如果您正在对用户进行身份验证），则可以立即检索终端用户的唯一 Amazon Cognito 标识符（身份 ID）：

```
var identityId = await credentials.GetIdentityIdAsync();
```

# 使用临时 AWS 服务 凭证进行访问
<a name="accessing-aws-services"></a>

使用身份池成功进行身份验证的结果是一组 AWS 凭证。使用这些证书，您的应用程序可以向受 IAM 身份验证保护的 AWS 资源发出请求。借助您可以添加到应用程序中以访问身份池 API 操作的各种 AWS SDKs 功能，您可以发出未经身份验证的 API 请求，从而生成临时证书。然后，您可以将其他 SDKs 内容 AWS 服务 添加到您的客户端，并使用这些临时证书签署请求。向您的临时凭证角色授予的 IAM 权限必须允许您从其他服务请求的操作。

在配置您的 Amazon Cognito 凭证提供程序并检索 AWS 证书后，创建一个 AWS 服务 客户端。以下是 AWS SDK 文档中的一些示例。

**AWS 用于创建客户端的 SDK 资源**
+ AWS 《 适用于 C\$1\$1 的 AWS SDK 开发人员指南》中的@@ [客户端配置](https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/client-config.html)
+ [将 适用于 Go 的 AWS SDK V2 与《 适用于 Go 的 AWS SDK 开发人员指南》 AWS 服务中的搭配](https://aws.github.io/aws-sdk-go-v2/docs/making-requests/)使用
+ 在《 AWS SDK for Java 2.x 开发人员指南》中@@ [配置 HTTP 客户端](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration.html)
+ 在《 适用于 JavaScript 的 AWS SDK 开发者指南》中@@ [创建和调用服务对象](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/creating-and-calling-service-objects.html)
+ 在 适用于 Python (Boto3) 的 AWS SDK 文档中@@ [创建客户端](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/clients.html#creating-clients)
+ 在《 适用于 Rust 的 AWS SDK 开发者指南》中@@ [创建服务客户端](https://docs.aws.amazon.com/sdk-for-rust/latest/dg/client.html)
+ 在《 适用于 Swift 的 AWS SDK 开发者指南》中@@ [使用客户端](https://docs.aws.amazon.com/sdk-for-swift/latest/developer-guide/using-client-services.html)

下面的代码段初始化 Amazon DynamoDB 客户端：

## Android
<a name="accessing-aws-services-1.android"></a>

要在安卓应用程序中使用 Amazon Cognito 身份池，请进行设置。 AWS Amplify有关更多信息，请参阅《Amplify 开发中心》**中的[身份验证](https://docs.amplify.aws/lib/auth/getting-started/q/platform/android/)。

```
// Create a service client with the provider
AmazonDynamoDB client = new AmazonDynamoDBClient(credentialsProvider);
```

 凭证提供者与 Amazon Cognito 通信，检索经过身份验证和未经身份验证的用户的唯一标识符，以及移动 SDK 的临时有限 AWS 权限证书。 AWS 检索到的凭证的有效期为 1 小时，提供程序会在凭证过期时进行刷新。

## iOS - Objective-C
<a name="accessing-aws-services-1.ios-objc"></a>

要在 iOS 应用程序中使用 Amazon Cognito 身份池，请进行设置。 AWS Amplify有关更多信息，请参阅《Amplify 开发中心》**中的 [Swift 身份验证](https://docs.amplify.aws/lib/auth/getting-started/q/platform/ios/)和 [Flutter 身份验证](https://docs.amplify.aws/lib/auth/getting-started/q/platform/flutter/)。

```
// create a configuration that uses the provider
AWSServiceConfiguration *configuration = [AWSServiceConfiguration configurationWithRegion:AWSRegionUSEast1 provider:credentialsProvider];
// get a client with the default service configuration
AWSDynamoDB *dynamoDB = [AWSDynamoDB defaultDynamoDB];
```

 凭证提供者与 Amazon Cognito 通信，检索经过身份验证和未经身份验证的用户的唯一标识符，以及移动 SDK 的临时有限 AWS 权限证书。 AWS 检索到的凭证的有效期为 1 小时，提供程序会在凭证过期时进行刷新。

## iOS - Swift
<a name="accessing-aws-services-1.ios-swift"></a>

要在 iOS 应用程序中使用 Amazon Cognito 身份池，请进行设置。 AWS Amplify有关更多信息，请参阅《Amplify 开发中心》**中的 [Swift 身份验证](https://docs.amplify.aws/lib/auth/getting-started/q/platform/ios/)。

```
// get a client with the default service configuration
let dynamoDB = AWSDynamoDB.default()

// get a client with a custom configuration
AWSDynamoDB.register(with: configuration!, forKey: "USWest2DynamoDB");
let dynamoDBCustom = AWSDynamoDB(forKey: "USWest2DynamoDB")
```

凭证提供者与 Amazon Cognito 通信，检索经过身份验证和未经身份验证的用户的唯一标识符，以及移动 SDK 的临时有限 AWS 权限证书。 AWS 检索到的凭证的有效期为 1 小时，提供程序会在凭证过期时进行刷新。

## JavaScript
<a name="accessing-aws-services-1.javascript"></a>



```
// Create a service client with the provider
var dynamodb = new AWS.DynamoDB({region: 'us-west-2'});
```

 凭证提供者与 Amazon Cognito 通信，检索经过身份验证和未经身份验证的用户的唯一标识符，以及移动 SDK 的临时 AWS 有限权限证书。 AWS 检索到的凭证的有效期为 1 小时，提供程序会在凭证过期时进行刷新。

## Unity
<a name="accessing-aws-services-1.unity"></a>

[适用于 Unity 的AWS SDK](https://docs.aws.amazon.com/mobile/sdkforunity/developerguide/what-is-unity-plugin.html) 现在是 [适用于 .NET 的 SDK](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/welcome.html) 的一部分。要开始使用中的亚马逊 Cognito 适用于 .NET 的 SDK，请参阅开发者指南中的[亚马逊 Cognito 凭证](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/cognito-creds-provider.html)提供商。 适用于 .NET 的 AWS SDK 或者，请参阅 [Amplify 开发者中心](https://docs.amplify.aws/)，了解用于构建应用程序的选项。 AWS Amplify

```
// create a service client that uses credentials provided by Cognito
AmazonDynamoDBClient client = new AmazonDynamoDBClient(credentials, REGION);
```

 凭证提供者与 Amazon Cognito 通信，检索经过身份验证和未经身份验证的用户的唯一标识符，以及移动 SDK 的临时 AWS 有限权限证书。 AWS 检索到的凭证的有效期为 1 小时，提供程序会在凭证过期时进行刷新。

## Xamarin
<a name="accessing-aws-services-1.xamarin"></a>

[适用于 Xamarin 的AWS SDK](https://docs.aws.amazon.com/mobile/sdkforxamarin/developerguide/Welcome.html) 现在是 [适用于 .NET 的 SDK](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/welcome.html) 的一部分。要开始使用中的亚马逊 Cognito 适用于 .NET 的 SDK，请参阅开发者指南中的[亚马逊 Cognito 凭证](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/cognito-creds-provider.html)提供商。 适用于 .NET 的 AWS SDK 或者，请参阅 [Amplify 开发者中心](https://docs.amplify.aws/)，了解用于构建应用程序的选项。 AWS Amplify

```
// create a service client that uses credentials provided by Cognito
var client = new AmazonDynamoDBClient(credentials, REGION)
```

 凭证提供者与 Amazon Cognito 通信，检索经过身份验证和未经身份验证的用户的唯一标识符，以及移动 SDK 的临时 AWS 有限权限证书。 AWS 检索到的凭证的有效期为 1 小时，提供程序会在凭证过期时进行刷新。

# 身份池第三方身份提供者
<a name="external-identity-providers"></a>

借助 Amazon Cognito 身份池，您可以与各种外部身份提供商 (IdPs) 集成，通过应用程序中的联合身份验证提供临时 AWS 证书。通过将您的身份池配置为使用这些外部 AWS 资源 IdPs，您可以通过 Amazon Cognito 用户池、社交提供商、OIDC 提供商或 SAML 提供商进行身份验证，授权您的用户访问后端资源。本节介绍设置和集成 IdPs Amazon Cognito 身份池的步骤。

使用 `logins` 属性，您可以设置从身份提供商 (IdP) 处收到的凭证。您也可以将一个身份池与多个身份池相关联 IdPs。例如，您可以在 `logins` 属性中设置 Facebook 和 Google 令牌，以将唯一的 Amazon Cognito 身份与两个 IdP 登录相关联。用户可以使用任一账户进行身份验证，但 Amazon Cognito 返回同一用户标识符。

以下说明将指导您使用 Amazon Cognito 身份池支持的身份池进行身份验证。 IdPs 

**Topics**
+ [将 Facebook 设置为身份池 IdP](facebook.md)
+ [设置 Login with Amazon 作为身份池 IdP](amazon.md)
+ [将 Google 设置为身份池 IdP](google.md)
+ [使用 Apple 作为身份池 IdP 来设置登录](apple.md)
+ [设置 OIDC 提供者作为身份池 IdP](open-id.md)
+ [设置 SAML 提供者作为身份池 IdP](saml-identity-provider.md)

# 将 Facebook 设置为身份池 IdP
<a name="facebook"></a>

Amazon Cognito 身份池与 Facebook 配合使用，以便针对应用程序用户提供联合身份验证。本部分介绍如何使用 Facebook 作为 IdP 来注册和设置应用程序。

## 设置 Facebook
<a name="set-up-facebook"></a>

在对 Facebook 用户进行身份验证并与 Facebook 互动之前，请先在 Facebook APIs 上注册

[Facebook 开发人员门户](https://developers.facebook.com/)可帮助您设置应用程序。在将 Facebook 集成到您的 Amazon Cognito 身份池之前，请执行以下过程：

**注意**  
Amazon Cognito 身份池联合身份验证与 [Facebook Limited Login](https://developers.facebook.com/docs/facebook-login/limited-login) 不兼容。有关如何在不超过 Limited Login 权限集的情况下设置 Facebook Login for iOS 的更多信息，请参阅 *Meta for Developers* 中的 [Facebook Login for iOS - 快速入门](https://developers.facebook.com/docs/facebook-login/ios)。

**设置 Facebook**

1. 在 [Facebook 开发人员门户](https://developers.facebook.com/)中，使用 Facebook 凭证登录。

1. 从 **Apps**（应用程序）菜单中，选择 **Add a New App**（添加新应用程序）。

1. 选择一个平台，然后完成快速启动流程。

### Android
<a name="set-up-facebook-1.android"></a>

有关如何将 Android 应用程序与 Facebook 登录集成的更多信息，请参阅 [Facebook 入门指南](https://developers.facebook.com/docs/android/getting-started)。

### iOS - Objective-C
<a name="set-up-facebook-1.ios-objc"></a>

有关如何将 OS Objective-C 应用程序与 Facebook 登录集成的更多信息，请参阅 [Facebook 入门指南](https://developers.facebook.com/docs/ios/getting-started/)。

### iOS - Swift
<a name="set-up-facebook-1.ios-swift"></a>

有关如何将 iOS Swift 应用程序与 Facebook 登录集成的更多信息，请参阅 [Facebook 入门指南](https://developers.facebook.com/docs/ios/getting-started/)。

### JavaScript
<a name="set-up-facebook-1.javascript"></a>

有关如何将 JavaScript 网络应用程序与 Facebook 登录集成的更多信息，请参阅 [Facebook 入门指南](https://developers.facebook.com/docs/facebook-login/login-flow-for-web/v2.3)。

## 在 Amazon Cognito 身份池控制台中配置身份提供者
<a name="configure-the-external-provider-in-the-amazon-cognito-console"></a>

使用以下过程配置身份提供者。

**添加 Facebook 身份提供者（IdP）**

1. 从 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)中选择**身份池**。选择身份池。

1. 选择**用户访问**选项卡。

1. 选择**添加身份提供者**。

1. 选择 **Facebook**。

1. 输入你在 [Meta 开发者版中创建的 OAuth ](https://developers.facebook.com/)项目的**应用程序 ID**。有关更多信息，请参阅《Meta for Developers 文档》**中的 [Facebook 登录](https://developers.facebook.com/docs/facebook-login/)。

1. 要设置 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时请求的角色，请配置**角色设置**。

   1. 您可以为该 IdP 中的用户分配您在配置**经过身份验证的角色**时设置的**原定设置角色**，也可以**使用规则选择角色**。

     1. 如果您选择**使用规则选择角色**，请输入用户身份验证中的来源**声明**、您要用来与声明进行比较的**运算符**、导致与该角色选择匹配的**值**，以及当**角色分配**匹配时要分配的**角色**。选择**添加其他**，以根据不同的条件创建其他规则。

     1. 选择**角色解析**。当用户的声明与您的规则不匹配时，您可以拒绝凭证或为**经过身份验证的角色**颁发凭证。

1. 要更改 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时分配的主体标签，请配置**访问控制属性**。

   1. 如果不应用主体标签，请选择**非活动**。

   1. 要基于 `sub` 和 `aud` 声明应用主体标签，请选择**使用原定设置映射**。

   1. 要为主体标签创建自己的自定义属性模式，请选择**使用自定义映射**。然后，对于您要在标签中表示的每个**声明**，输入要从该声明中获取的**标签键**。

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

## 使用 Facebook
<a name="using-facebook"></a>

### Android
<a name="using-facebook-1.android"></a>

要添加 Facebook 身份验证，请先按照 [Facebook 指南](https://developers.facebook.com/docs/android)将 Facebook 开发工具包集成到应用程序中。然后，将 [**Login with Facebook**（使用 Facebook 登录）按钮](https://developers.facebook.com/docs/facebook-login/android)添加到 Android 用户界面。Facebook 开发工具包使用会话对象跟踪其状态。Amazon Cognito 使用来自此会话对象的访问令牌对用户进行身份验证，生成唯一标识符，并在需要时授予用户访问其他 AWS 资源的权限。

使用 Facebook 开发工具包对用户进行身份验证后，将会话令牌添加到 Amazon Cognito 凭证提供程序中。

Facebook SDK 4.0 或更高版本：

```
Map<String, String> logins = new HashMap<String, String>();
logins.put("graph.facebook.com", AccessToken.getCurrentAccessToken().getToken());
credentialsProvider.setLogins(logins);
```

Facebook SDK 4.0 之前的版本：

```
Map<String, String> logins = new HashMap<String, String>();
logins.put("graph.facebook.com", Session.getActiveSession().getAccessToken());
credentialsProvider.setLogins(logins);
```

Facebook 登录流程在其开发工具包中初始化一个单例会话。Facebook 会话对象包含一个 OAuth 令牌，Amazon Cognito 使用该令牌为经过身份验证的最终用户生成 AWS 证书。Amazon Cognito 还使用该令牌检查用户数据库，以确定是否存在与此特定 Facebook 身份匹配的用户。如果用户已存在，则 API 会返回现有的标识符。否则，API 将返回新的标识符。客户端开发工具包会自动在本地设备上缓存标识符。

**注意**  
设置登录映射后，调用`refresh`或`get`检索 AWS 证书。

### iOS - Objective-C
<a name="using-facebook-1.ios-objc"></a>

要添加 Facebook 身份验证，请先按照 [Facebook 指南](https://developers.facebook.com/docs/ios)将 Facebook 开发工具包集成到应用程序中。然后，向用户界面添加[“用 Facebook 登录”按钮](https://developers.facebook.com/docs/facebook-login/ios)。Facebook 开发工具包使用会话对象跟踪其状态。Amazon Cognito 使用来自此会话对象的访问令牌对用户进行身份验证，并将其绑定到唯一的 Amazon Cognito 身份池（联合身份）。

要向 Amazon Cognito 提供 Facebook 访问令牌，请实施 [https://github.com/aws-amplify/aws-sdk-ios](https://github.com/aws-amplify/aws-sdk-ios) 协议。

在实施 `logins` 方法时，返回一个包含 `AWSIdentityProviderFacebook` 的词典。此词典充当键，而经过身份验证的 Facebook 用户的当前访问令牌充当值，如以下代码示例所示。

```
- (AWSTask<NSDictionary<NSString *, NSString *> *> *)logins {
    FBSDKAccessToken* fbToken = [FBSDKAccessToken currentAccessToken];
    if(fbToken){
        NSString *token = fbToken.tokenString;
        return [AWSTask taskWithResult: @{ AWSIdentityProviderFacebook : token }];
    }else{
            return [AWSTask taskWithError:[NSError errorWithDomain:@"Facebook Login"
                                                          code:-1
                                                      userInfo:@{@"error":@"No current Facebook access token"}]];
    }
}
```

当您实例化 `AWSCognitoCredentialsProvider` 时，在构造函数中传递实施 `AWSIdentityProviderManager` 作为 `identityProviderManager` 的值的类。有关更多信息，请转到[AWSCognitoCredentialsProvider](https://github.com/aws-amplify/aws-sdk-ios)参考页面并选择**initWithRegion类型:identityPoolId: identityProviderManager**。

### iOS - Swift
<a name="using-facebook-1.ios-swift"></a>

要添加 Facebook 身份验证，请先按照 [Facebook 指南](https://developers.facebook.com/docs/ios)将 Facebook 开发工具包集成到应用程序中。然后，向用户界面添加[“用 Facebook 登录”按钮](https://developers.facebook.com/docs/facebook-login/ios)。Facebook 开发工具包使用会话对象跟踪其状态。Amazon Cognito 使用来自此会话对象的访问令牌对用户进行身份验证，并将其绑定到唯一的 Amazon Cognito 身份池（联合身份）。

**注意**  
Amazon Cognito 身份池联合身份验证与 [Facebook Limited Login](https://developers.facebook.com/docs/facebook-login/limited-login) 不兼容。有关如何在不超过 Limited Login 权限集的情况下设置 Facebook Login for iOS 的更多信息，请参阅 *Meta for Developers* 中的 [Facebook Login for iOS - 快速入门](https://developers.facebook.com/docs/facebook-login/ios)。

要向 Amazon Cognito 提供 Facebook 访问令牌，请实施 [https://github.com/aws-amplify/aws-sdk-ios](https://github.com/aws-amplify/aws-sdk-ios) 协议。

在实施 `logins` 方法时，返回一个包含 `AWSIdentityProviderFacebook` 的词典。此词典充当键，而经过身份验证的 Facebook 用户的当前访问令牌充当值，如以下代码示例所示。

```
class FacebookProvider: NSObject, AWSIdentityProviderManager {
    func logins() -> AWSTask<NSDictionary> {
        if let token = AccessToken.current?.authenticationToken {
            return AWSTask(result: [AWSIdentityProviderFacebook:token])
        }
        return AWSTask(error:NSError(domain: "Facebook Login", code: -1 , userInfo: ["Facebook" : "No current Facebook access token"]))
    }
}
```

当您实例化 `AWSCognitoCredentialsProvider` 时，在构造函数中传递实施 `AWSIdentityProviderManager` 作为 `identityProviderManager` 的值的类。有关更多信息，请转到[https://github.com/aws-amplify/aws-sdk-ios](https://github.com/aws-amplify/aws-sdk-ios)参考页面并选择**initWithRegion类型:identityPoolId: identityProviderManager**。

### JavaScript
<a name="using-facebook-1.javascript"></a>

要添加 Facebook 身份验证，请按照[适用于 Web 的 Facebook 登录](https://developers.facebook.com/docs/facebook-login/login-flow-for-web/v2.3)中的说明操作，并在您的网站上添加 **Login with Facebook** （使用 Facebook 登录）按钮。Facebook 开发工具包使用会话对象跟踪其状态。Amazon Cognito 使用来自此会话对象的访问令牌对用户进行身份验证，生成唯一标识符，并在需要时授予用户访问其他 AWS 资源的权限。

使用 Facebook 开发工具包对用户进行身份验证后，将会话令牌添加到 Amazon Cognito 凭证提供程序中。

```
FB.login(function (response) {

  // Check if the user logged in successfully.
  if (response.authResponse) {

    console.log('You are now logged in.');

    // Add the Facebook access token to the Amazon Cognito credentials login map.
    AWS.config.credentials = new AWS.CognitoIdentityCredentials({
      IdentityPoolId: 'IDENTITY_POOL_ID',
      Logins: {
        'graph.facebook.com': response.authResponse.accessToken
      }
    });

    // Obtain AWS credentials
    AWS.config.credentials.get(function(){
        // Access AWS resources here.
    });

  } else {
    console.log('There was a problem logging you in.');
  }

});
```

Facebook 软件开发工具包获取 OAuth 令牌，亚马逊 Cognito 使用该令牌为经过身份验证的最终用户 AWS 生成证书。Amazon Cognito 还可以使用该令牌检查用户数据库，以确定是否存在与此特定 Facebook 身份匹配的用户。如果用户已存在，则 API 会返回现有的标识符。否则，将返回新的标识符。标识符由本地设备上的客户端开发工具包自动缓存。

**注意**  
设置登录映射后，请调用 `refresh` 或 `get` 以获取凭证。有关代码示例，请参阅[JavaScript 自述文件](https://github.com/amazon-archives/amazon-cognito-identity-js/blob/master/README.md)中的 “用例 17，将用户池与 Cognito 身份集成”。

### Unity
<a name="using-facebook-1.unity"></a>

要添加 Facebook 身份验证，请先按照 [Facebook 指南](https://developers.facebook.com/docs/unity)将 Facebook 开发工具包集成到应用程序中。Amazon Cognito 使用 `FB` 对象中的 Facebook 访问令牌生成与 Amazon Cognito 身份关联的唯一用户标识符。

使用 Facebook 开发工具包对用户进行身份验证后，将会话令牌添加到 Amazon Cognito 凭证提供程序：

```
void Start()
{
    FB.Init(delegate() {
        if (FB.IsLoggedIn) { //User already logged in from a previous session
            AddFacebookTokenToCognito();
        } else {
            FB.Login ("email", FacebookLoginCallback);
        }
    });
}

void FacebookLoginCallback(FBResult result)
{
    if (FB.IsLoggedIn)
    {
        AddFacebookTokenToCognito();
    }
    else
    {
        Debug.Log("FB Login error");
    }
}

void AddFacebookTokenToCognito()
{
    credentials.AddLogin ("graph.facebook.com", AccessToken.CurrentAccessToken.TokenString);
}
```

使用 `FB.AccessToken` 之前，调用 `FB.Login()` 并确保 `FB.IsLoggedIn` 为 True。

### Xamarin
<a name="using-facebook-1.xamarin"></a>

**Xamarin for Android：**

```
public void InitializeFacebook() {
    FacebookSdk.SdkInitialize(this.ApplicationContext);
    callbackManager = CallbackManagerFactory.Create();
    LoginManager.Instance.RegisterCallback(callbackManager, new FacebookCallback &lt; LoginResult &gt; () {
      HandleSuccess = loginResult = &gt; {
        var accessToken = loginResult.AccessToken;
        credentials.AddLogin("graph.facebook.com", accessToken.Token);
        //open new activity
      },
      HandleCancel = () = &gt; {
        //throw error message
      },
      HandleError = loginError = &gt; {
        //throw error message
      }
    });
    LoginManager.Instance.LogInWithReadPermissions(this, new List &lt; string &gt; {
      "public_profile"
    });
  }
```

**Xamarin for iOS：**

```
public void InitializeFacebook() {
  LoginManager login = new LoginManager();
  login.LogInWithReadPermissions(readPermissions.ToArray(), delegate(LoginManagerLoginResult result, NSError error) {
    if (error != null) {
      //throw error message
    } else if (result.IsCancelled) {
      //throw error message
    } else {
      var accessToken = loginResult.AccessToken;
      credentials.AddLogin("graph.facebook.com", accessToken.Token);
      //open new view controller
    }
  });
}
```

# 设置 Login with Amazon 作为身份池 IdP
<a name="amazon"></a>

Amazon Cognito 身份池与 Login with Amazon 配合使用，以便针对移动应用程序和 Web 应用程序用户提供联合身份验证。本部分介绍如何使用 Login with Amazon（使用亚马逊账号登录）作为身份提供商 (IdP) 来注册和设置应用程序。

在[开发人员门户](https://developer.amazon.com/login-with-amazon)中设置 Login with Amazon（使用亚马逊账号登录）用于 Amazon Cognito。有关更多信息，请参阅 Login with Amazon（使用亚马逊账号登录）常见问题中的[设置 Login with Amazon（使用亚马逊账号登录）](https://developer.amazon.com/docs/login-with-amazon/faq.html#setting-up-login-with-amazon)。

**注意**  
要将 Login with Amazon（使用亚马逊账号登录）集成到 Xamarin 应用程序中，请按照 [Xamarin 入门指南](https://developer.xamarin.com/guides/cross-platform/getting_started/)中的说明操作。

**注意**  
您无法在 Unity 平台上原生集成 Login with Amazon（使用亚马逊账号登录）。请使用 Web 视图并完成浏览器登录流程。

## 设置 Login with Amazon（使用亚马逊账号登录）
<a name="login-with-amazon-setup"></a>

**实施 Login with Amazon（使用亚马逊账号登录）**

在[亚马逊开发者门户](https://developer.amazon.com/apps-and-games/login-with-amazon)中，您可以设置 OAuth 应用程序以与您的身份池集成，查找 Login with Amazon 文档，然后下载 SDKs。选择 **Developer console**（开发人员控制台），然后在开发人员门户中选择 **Login with Amazon**（使用亚马逊账号登录）。您可以为您的应用程序创建一个安全配置文件，然后在您的应用程序中构建 Login with Amazon（使用亚马逊账号登录）身份验证机制。请参阅[获取凭证](getting-credentials.md)，了解有关如何将 Login with Amazon（使用亚马逊账号登录）身份验证与应用程序集成的更多信息

Amazon 会为您的新安全配置文件发放 OAuth 2.0 **客户端 ID**。您可以在安全配置文件的 **Web Settings**（Web 设置）选项卡上找到 **client ID**（客户端 ID）。在您身份池中的“通过 Amazon 登录”IdP 的**应用程序 ID** 字段中输入**安全配置文件 ID**。

**注意**  
在您身份池中的“通过 Amazon 登录”IdP 的**应用程序 ID** 字段中输入**安全配置文件 ID**。这与使用**客户端 ID** 的用户池不同。

## 在 Amazon Cognito 控制台中配置外部提供商
<a name="login-with-amazon-configure-provider"></a>

**添加 Login with Amazon 身份提供者（IdP）**

1. 从 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)中选择**身份池**。选择身份池。

1. 选择**用户访问**选项卡。

1. 选择**添加身份提供者**。

1. 选择 **Login with Amazon**。

1. 输入您在 Lo [gin with Amazon 上创建的 OAuth ](https://developer.amazon.com/apps-and-games/login-with-amazon)项目的**应用程序 ID**。有关更多信息，请参阅 [Login with Amazon 文档](https://developer.amazon.com/docs/login-with-amazon/documentation-overview.html)。

1. 要设置 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时请求的角色，请配置**角色设置**。

   1. 您可以为该 IdP 中的用户分配您在配置**经过身份验证的角色**时设置的**原定设置角色**，也可以**使用规则选择角色**。

     1. 如果您选择**使用规则选择角色**，请输入用户身份验证中的来源**声明**、您要用来与声明进行比较的**运算符**、导致与该角色选择匹配的**值**，以及当**角色分配**匹配时要分配的**角色**。选择**添加其他**，以根据不同的条件创建其他规则。

     1. 选择**角色解析**。当用户的声明与您的规则不匹配时，您可以拒绝凭证或为**经过身份验证的角色**颁发凭证。

1. 要更改 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时分配的主体标签，请配置**访问控制属性**。

   1. 如果不应用主体标签，请选择**非活动**。

   1. 要基于 `sub` 和 `aud` 声明应用主体标签，请选择**使用原定设置映射**。

   1. 要为主体标签创建自己的自定义属性模式，请选择**使用自定义映射**。然后，对于您要在标签中表示的每个**声明**，输入要从该声明中获取的**标签键**。

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

## 使用 Login with Amazon：Android
<a name="set-up-amazon-1.android"></a>

对亚马逊登录进行身份验证后，您可以通过界面的 onSuccess 方法将令牌传递给 Amazon Cognito 凭证提供商。 TokenListener 代码如下所示：

```
@Override
public void onSuccess(Bundle response) {
    String token = response.getString(AuthzConstants.BUNDLE_KEY.TOKEN.val);
    Map<String, String> logins = new HashMap<String, String>();
    logins.put("www.amazon.com", token);
    credentialsProvider.setLogins(logins);
}
```

## 使用 Login with Amazon：iOS - Objective-C
<a name="set-up-amazon-1.ios-objc"></a>

对亚马逊登录进行身份验证后，您可以通过以下 requestDidSucceed 方法将令牌传递给 Amazon Cognito 凭证提供商： AMZNAccessTokenDelegate

```
- (void)requestDidSucceed:(APIResult \*)apiResult {
    if (apiResult.api == kAPIAuthorizeUser) {
        [AIMobileLib getAccessTokenForScopes:[NSArray arrayWithObject:@"profile"] withOverrideParams:nil delegate:self];
    }
    else if (apiResult.api == kAPIGetAccessToken) {
        credentialsProvider.logins = @{ @(AWSCognitoLoginProviderKeyLoginWithAmazon): apiResult.result };
    }
}}
```

## 使用 Login with Amazon：iOS - Swift
<a name="set-up-amazon-1.ios-swift"></a>

在对 Amazon 登录进行身份验证后，您可以在 `AMZNAccessTokenDelegate` 的 `requestDidSucceed` 方法中将令牌传递给 Amazon Cognito 凭证提供程序：

```
func requestDidSucceed(apiResult: APIResult!) {
    if apiResult.api == API.AuthorizeUser {
        AIMobileLib.getAccessTokenForScopes(["profile"], withOverrideParams: nil, delegate: self)
    } else if apiResult.api == API.GetAccessToken {
        credentialsProvider.logins = [AWSCognitoLoginProviderKey.LoginWithAmazon.rawValue: apiResult.result]
    }
}
```

## 使用 Login with Amazon： JavaScript
<a name="set-up-amazon-1.javascript"></a>

在用户通过 Login with Amazon 进行身份验证并重定向回网站后，系统会在查询字符串中提供 Login with Amazon access\$1token。将此令牌传递到凭证登录映射。

```
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
   IdentityPoolId: 'IDENTITY_POOL_ID',
   Logins: {
       'www.amazon.com': 'Amazon Access Token'
   }
});
```

# 将 Google 设置为身份池 IdP
<a name="google"></a>

Amazon Cognito 身份池与 Google 配合使用，以便针对移动应用程序用户提供联合身份验证。本部分介绍如何使用 Google 作为 IdP 来注册和设置应用程序。

## Android
<a name="set-up-google-1.android"></a>

**注意**  
如果您的应用程序使用 Google 并且可在多个移动平台上使用，则应将 Google 配置为 [OpenID Connect 提供商](open-id.md)。将所有创建的客户添加 IDs 为其他受众值，以实现更好的集成。要了解有关 Google 跨客户端身份模式的更多信息，请参阅[跨客户端身份](https://developers.google.com/accounts/docs/CrossClientAuth)。

**设置 Google**

要激活 Google Sign-in for Android，请为应用程序创建 Google Developers 控制台项目。

1. 转到 [Google Developers 控制台](https://console.developers.google.com/)并创建一个新项目。

1. 选择**APIs 和服务**，然后选择**OAuth 同意屏幕**。自定义 Google 在征求用户同意以便与您的应用共享个人资料数据时向用户显示的信息。

1. 选择 **Credentials**（凭证），然后选择 **Create credentials**（创建凭证）。选择**OAuth 客户端 ID**。选择 **Android** 作为 **Application type**（应用程序类型）。为开发应用程序的每个平台创建单独的客户端 ID。

1. 从 **Credentials**（凭证）中，选择 **Manage service accounts**（管理服务账户）。选择 **Create service account**（创建服务账户）。输入服务账户详细信息，然后选择 **Create and continue**（创建并继续）。

1. 授予服务账户对项目的访问权限。根据应用程序的要求授予用户访问服务账户的权限。

1. 选择您的新服务账户，选择 **Keys**（密钥）选项卡，然后选择 **Add key**（添加密钥）。创建并下载新的 JSON 密钥。

有关如何使用 Google Developers 控制台的更多信息，请参阅 Google Cloud 文档中的[创建和管理项目](https://cloud.google.com/resource-manager/docs/creating-managing-projects)。

有关如何将 Google 集成到 Android 应用程序的更多信息，请参阅 Google Identity 文档中的[使用 Sign in with Google 验证用户身份](https://developer.android.com/identity/sign-in/credential-manager-siwg)。

**添加 Google 身份提供者（IdP）**

1. 从 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)中选择**身份池**。选择身份池。

1. 选择**用户访问**选项卡。

1. 选择**添加身份提供者**。

1. 选择 **Google**。

1. 输入您在[谷歌云平台](https://console.cloud.google.com/)上创建的 OAuth 项目的**客户端 ID**。有关更多信息，请参阅 *Google 云平台控制台帮助*中的[设置 OAuth 2.0](https://support.google.com/cloud/answer/6158849)。

1. 要设置 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时请求的角色，请配置**角色设置**。

   1. 您可以为该 IdP 中的用户分配您在配置**经过身份验证的角色**时设置的**原定设置角色**，也可以**使用规则选择角色**。

     1. 如果您选择**使用规则选择角色**，请输入用户身份验证中的来源**声明**、您要用来与声明进行比较的**运算符**、导致与该角色选择匹配的**值**，以及当**角色分配**匹配时要分配的**角色**。选择**添加其他**，以根据不同的条件创建其他规则。

     1. 选择**角色解析**。当用户的声明与您的规则不匹配时，您可以拒绝凭证或为**经过身份验证的角色**颁发凭证。

1. 要更改 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时分配的主体标签，请配置**访问控制属性**。

   1. 如果不应用主体标签，请选择**非活动**。

   1. 要基于 `sub` 和 `aud` 声明应用主体标签，请选择**使用原定设置映射**。

   1. 要为主体标签创建自己的自定义属性模式，请选择**使用自定义映射**。然后，对于您要在标签中表示的每个**声明**，输入要从该声明中获取的**标签键**。

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

**使用 Google**

要在应用程序中启用 Login with Google，请按照[适用于 Android 的 Google 文档](https://developers.google.com/identity/sign-in/android/start)中的说明执行操作。当用户登录时，他们向 Google 请求 OpenID Connect 身份验证令牌。然后，Amazon Cognito 将使用该令牌对用户进行身份验证并生成一个唯一标识符。

以下示例代码显示如何从 Google Play 服务检索身份验证令牌：

```
GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
AccountManager am = AccountManager.get(this);
Account[] accounts = am.getAccountsByType(GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);
String token = GoogleAuthUtil.getToken(getApplicationContext(), accounts[0].name,
        "audience:server:client_id:YOUR_GOOGLE_CLIENT_ID");
Map<String, String> logins = new HashMap<String, String>();
logins.put("accounts.google.com", token);
credentialsProvider.setLogins(logins);
```

## iOS - Objective-C
<a name="set-up-google-1.ios-objc"></a>

**注意**  
如果您的应用程序使用 Google 并且可在多个移动平台上使用，则应将 Google 配置为 [OpenID Connect 提供商](open-id.md)。将所有创建的客户添加 IDs 为其他受众值，以实现更好的集成。要了解有关 Google 跨客户端身份模式的更多信息，请参阅[跨客户端身份](https://developers.google.com/accounts/docs/CrossClientAuth)。

**设置 Google**

要启用 Google Sign-in for iOS，请为应用程序创建 Google Developers 控制台项目。

1. 转到 [Google Developers 控制台](https://console.developers.google.com/)并创建一个新项目。

1. 选择**APIs 和服务**，然后选择**OAuth 同意屏幕**。自定义 Google 在征求用户同意以便与您的应用共享个人资料数据时向用户显示的信息。

1. 选择 **Credentials**（凭证），然后选择 **Create credentials**（创建凭证）。选择**OAuth 客户端 ID**。选择 **iOS** 作为 **Application type**（应用程序类型）。为开发应用程序的每个平台创建单独的客户端 ID。

1. 从 **Credentials**（凭证）中，选择 **Manage service accounts**（管理服务账户）。选择 **Create service account**（创建服务账户）。输入服务账户详细信息，然后选择 **Create and continue**（创建并继续）。

1. 授予服务账户对项目的访问权限。根据应用程序的要求授予用户访问服务账户的权限。

1. 选择您的新服务账户。选择 **Keys**（密钥）选项卡，然后选择 **Add key**（添加密钥）。创建并下载新的 JSON 密钥。

有关如何使用 Google Developers 控制台的更多信息，请参阅 Google Cloud 文档中的[创建和管理项目](https://cloud.google.com/resource-manager/docs/creating-managing-projects)。

有关将 Google 集成到 iOS 应用程序的更多信息，请参阅 Google Identity 文档中的 [Google Sign-In for iOS](https://developers.google.com/identity/sign-in/ios/start-integrating)。

**添加 Google 身份提供者（IdP）**

1. 从 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)中选择**身份池**。选择身份池。

1. 选择**用户访问**选项卡。

1. 选择**添加身份提供者**。

1. 选择 **Google**。

1. 输入您在[谷歌云平台](https://console.cloud.google.com/)上创建的 OAuth 项目的**客户端 ID**。有关更多信息，请参阅 *Google 云平台控制台帮助*中的[设置 OAuth 2.0](https://support.google.com/cloud/answer/6158849)。

1. 要设置 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时请求的角色，请配置**角色设置**。

   1. 您可以为该 IdP 中的用户分配您在配置**经过身份验证的角色**时设置的**原定设置角色**，也可以**使用规则选择角色**。

     1. 如果您选择**使用规则选择角色**，请输入用户身份验证中的来源**声明**、您要用来与声明进行比较的**运算符**、导致与该角色选择匹配的**值**，以及当**角色分配**匹配时要分配的**角色**。选择**添加其他**，以根据不同的条件创建其他规则。

     1. 选择**角色解析**。当用户的声明与您的规则不匹配时，您可以拒绝凭证或为**经过身份验证的角色**颁发凭证。

1. 要更改 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时分配的主体标签，请配置**访问控制属性**。

   1. 如果不应用主体标签，请选择**非活动**。

   1. 要基于 `sub` 和 `aud` 声明应用主体标签，请选择**使用原定设置映射**。

   1. 要为主体标签创建自己的自定义属性模式，请选择**使用自定义映射**。然后，对于您要在标签中表示的每个**声明**，输入要从该声明中获取的**标签键**。

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

**使用 Google**

要在应用程序中启用“用 Google 登录”，请按照[适用于 iOS 的 Google 文档](https://developers.google.com/identity/sign-in/ios/start/)中的说明执行操作。成功通过身份验证后，将生成一个 OpenID Connect 身份验证令牌，供 Amazon Cognito 用于对用户进行身份验证并生成一个唯一标识符。

成功通过身份验证后，将生成一个 `GTMOAuth2Authentication` 对象，其中包含一个 `id_token`，供 Amazon Cognito 用于对用户进行身份验证并生成一个唯一标识符：

```
- (void)finishedWithAuth: (GTMOAuth2Authentication *)auth error: (NSError *) error {
        NSString *idToken = [auth.parameters objectForKey:@"id_token"];
        credentialsProvider.logins = @{ @(AWSCognitoLoginProviderKeyGoogle): idToken };
    }
```

## iOS - Swift
<a name="set-up-google-1.ios-swift"></a>

**注意**  
如果您的应用程序使用 Google 并且可在多个移动平台上使用，则应将 Google 配置为 [OpenID Connect 提供商](open-id.md)。将所有创建的客户添加 IDs 为其他受众值，以实现更好的集成。要了解有关 Google 跨客户端身份模式的更多信息，请参阅[跨客户端身份](https://developers.google.com/accounts/docs/CrossClientAuth)。

**设置 Google**

要启用 Google Sign-in for iOS，请为应用程序创建 Google Developers 控制台项目。

1. 转到 [Google Developers 控制台](https://console.developers.google.com/)并创建一个新项目。

1. 选择**APIs 和服务**，然后选择**OAuth 同意屏幕**。自定义 Google 在征求用户同意以便与您的应用共享个人资料数据时向用户显示的信息。

1. 选择 **Credentials**（凭证），然后选择 **Create credentials**（创建凭证）。选择**OAuth 客户端 ID**。选择 **iOS** 作为 **Application type**（应用程序类型）。为开发应用程序的每个平台创建单独的客户端 ID。

1. 从 **Credentials**（凭证）中，选择 **Manage service accounts**（管理服务账户）。选择 **Create service account**（创建服务账户）。输入服务账户详细信息，然后选择 **Create and continue**（创建并继续）。

1. 授予服务账户对项目的访问权限。根据应用程序的要求授予用户访问服务账户的权限。

1. 选择您的新服务账户，选择 **Keys**（密钥）选项卡，然后选择 **Add key**（添加密钥）。创建并下载新的 JSON 密钥。

有关如何使用 Google Developers 控制台的更多信息，请参阅 Google Cloud 文档中的[创建和管理项目](https://cloud.google.com/resource-manager/docs/creating-managing-projects)。

有关将 Google 集成到 iOS 应用程序的更多信息，请参阅 Google Identity 文档中的 [Google Sign-In for iOS](https://developers.google.com/identity/sign-in/ios/start-integrating)。

在 [Amazon Cognito 控制台主页](https://console.aws.amazon.com/cognito/home)中选择 **Manage Identity Pools**（管理身份池）：

**在 Amazon Cognito 控制台中配置外部提供商**

1. 选择想要在其中启用 Google 作为外部提供商的身份池的名称。此时将显示身份池的 **Dashboard**（控制面板）页。

1. 在**控制面板**页面的右上角，选择 **Edit identity pool (编辑身份池)**。此时将显示“Edit identity pool”（编辑身份池）页。

1. 向下滚动并选择 **Authentication providers**（身份验证提供商）以展开这一部分。

1. 选择 **Google** 选项卡。

1. 选择 **Unlock**（解锁）。

1. 输入从 Google 获取的 Google 客户端 ID，然后选择 **Save Changes**（保存更改）。

**使用 Google**

要在应用程序中启用“用 Google 登录”，请按照[适用于 iOS 的 Google 文档](https://developers.google.com/identity/sign-in/ios/start/)中的说明执行操作。成功通过身份验证后，将生成一个 OpenID Connect 身份验证令牌，供 Amazon Cognito 用于对用户进行身份验证并生成一个唯一标识符。

成功的身份验证会生成一个包含 `id_token` 的 `GTMOAuth2Authentication` 对象。Amazon Cognito 使用此令牌对用户进行身份验证并生成一个唯一标识符：

```
func finishedWithAuth(auth: GTMOAuth2Authentication!, error: NSError!) {
    if error != nil {
      print(error.localizedDescription)
    }
    else {
      let idToken = auth.parameters.objectForKey("id_token")
      credentialsProvider.logins = [AWSCognitoLoginProviderKey.Google.rawValue: idToken!]
    }
}
```

## JavaScript
<a name="set-up-google-1.javascript"></a>

**注意**  
如果您的应用程序使用 Google 并且可在多个移动平台上使用，则应将 Google 配置为 [OpenID Connect 提供商](open-id.md)。将所有创建的客户添加 IDs 为其他受众值，以实现更好的集成。要了解有关 Google 跨客户端身份模式的更多信息，请参阅[跨客户端身份](https://developers.google.com/accounts/docs/CrossClientAuth)。

**设置 Google**

要为 JavaScript 网络应用程序启用 Google 登录，请为您的应用程序创建 Google 开发者控制台项目。

1. 转到 [Google Developers 控制台](https://console.developers.google.com/)并创建一个新项目。

1. 选择**APIs 和服务**，然后选择**OAuth 同意屏幕**。自定义 Google 在征求用户同意以便与您的应用共享个人资料数据时向用户显示的信息。

1. 选择 **Credentials**（凭证），然后选择 **Create credentials**（创建凭证）。选择**OAuth 客户端 ID**。选择 **Web application**（Web 应用程序）作为 **Application type**（应用程序类型）。为开发应用程序的每个平台创建单独的客户端 ID。

1. 从 **Credentials**（凭证）中，选择 **Manage service accounts**（管理服务账户）。选择 **Create service account**（创建服务账户）。输入服务账户详细信息，然后选择 **Create and continue**（创建并继续）。

1. 授予服务账户对项目的访问权限。根据应用程序的要求授予用户访问服务账户的权限。

1. 选择您的新服务账户，选择 **Keys**（密钥）选项卡，然后选择 **Add key**（添加密钥）。创建并下载新的 JSON 密钥。

有关如何使用 Google Developers 控制台的更多信息，请参阅 Google Cloud 文档中的[创建和管理项目](https://cloud.google.com/resource-manager/docs/creating-managing-projects)。

有关如何将 Google 集成到 Web 应用程序的更多信息，请参阅 Google Identity 文档中的[使用 Google 登录](https://developers.google.com/identity/gsi/web/guides/overview)。

**在 Amazon Cognito 控制台中配置外部提供商**

**添加 Google 身份提供者（IdP）**

1. 从 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)中选择**身份池**。选择身份池。

1. 选择**用户访问**选项卡。

1. 选择**添加身份提供者**。

1. 选择 **Google**。

1. 输入您在[谷歌云平台](https://console.cloud.google.com/)上创建的 OAuth 项目的**客户端 ID**。有关更多信息，请参阅 *Google 云平台控制台帮助*中的[设置 OAuth 2.0](https://support.google.com/cloud/answer/6158849)。

1. 要设置 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时请求的角色，请配置**角色设置**。

   1. 您可以为该 IdP 中的用户分配您在配置**经过身份验证的角色**时设置的**原定设置角色**，也可以**使用规则选择角色**。

     1. 如果您选择**使用规则选择角色**，请输入用户身份验证中的来源**声明**、您要用来与声明进行比较的**运算符**、导致与该角色选择匹配的**值**，以及当**角色分配**匹配时要分配的**角色**。选择**添加其他**，以根据不同的条件创建其他规则。

     1. 选择**角色解析**。当用户的声明与您的规则不匹配时，您可以拒绝凭证或为**经过身份验证的角色**颁发凭证。

1. 要更改 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时分配的主体标签，请配置**访问控制属性**。

   1. 如果不应用主体标签，请选择**非活动**。

   1. 要基于 `sub` 和 `aud` 声明应用主体标签，请选择**使用原定设置映射**。

   1. 要为主体标签创建自己的自定义属性模式，请选择**使用自定义映射**。然后，对于您要在标签中表示的每个**声明**，输入要从该声明中获取的**标签键**。

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

**使用 Google**

要在应用程序中启用“用 Google 登录”，请按照[适用于 Web 的 Google 文档](https://developers.google.com/identity/gsi/web/guides/overview)中的说明执行操作。

成功通过身份验证后，将生成一个响应对象，其中包含一个 `id_token`，供 Amazon Cognito 用于对用户进行身份验证并生成一个唯一标识符：

```
function signinCallback(authResult) {
  if (authResult['status']['signed_in']) {

     // Add the Google access token to the Amazon Cognito credentials login map.
     AWS.config.credentials = new AWS.CognitoIdentityCredentials({
        IdentityPoolId: 'IDENTITY_POOL_ID',
        Logins: {
           'accounts.google.com': authResult['id_token']
        }
     });

     // Obtain AWS credentials
     AWS.config.credentials.get(function(){
        // Access AWS resources here.
     });
  }
}
```

# 使用 Apple 作为身份池 IdP 来设置登录
<a name="apple"></a>

Amazon Cognito 身份池与“通过 Apple 登录”配合使用，以便针对移动应用程序和 Web 应用程序用户提供联合身份验证。本节介绍如何使用 Sign in with Apple（使用苹果账号登录）作为身份提供商 (IdP) 来注册和设置应用程序。

要将 Sign in with Apple 作为身份验证提供商添加到身份池，您必须完成两个过程。首先，在应用程序中集成 Sign in with Apple（使用苹果账号登录），然后在身份池中配置 Sign in with Apple（使用苹果账号登录）。有关设置 “使用 Apple 登录” 的 up-to-date更多信息，请参阅 Apple 开发者文档[中的配置环境以使用 Apple 登录](https://developer.apple.com/documentation/signinwithapple/configuring-your-environment-for-sign-in-with-apple)。

## 设置 Sign in with Apple
<a name="login-with-apple-setup"></a>

要将 Sign in with Apple（使用苹果账号登录）配置为 IdP，您必须向 Apple 注册您的应用程序才能接收客户端 ID。

1. 创建 [Apple 开发人员账户](https://developer.apple.com/programs/enroll/)。

1. 使用 Apple 凭证[登录](https://developer.apple.com/account/#/welcome)。

1. 在左侧导航窗格中，选择 “**证书 IDs 和配置文件**”。

1. 在左侧导航窗格中，选择**Identifiers**（标识符）。

1. 在 **Identifiers**（标识符）页面上，选择 **\$1** 图标。

1. 在 “**注册新标识符**” 页面上，选择 “**应用程序**” IDs，然后选择 “**继续**”。

1. 在 **Register an App ID**（注册应用程序 ID）页面上，执行以下操作：

   1. 在 **Description**（描述）下方，键入描述。

   1. 在 **Bundle ID**（服务包 ID）下，键入标识符。记下此 **Bundle ID**（捆绑包 ID），因为您需要此值才能将 Apple 配置为身份池中的提供商。

   1. 在 **Capabilities**（功能）下，选择 **Sign In with Apple**，然后选择 **Edit**（编辑）。

   1. 在**通过 Apple 登录：应用程序 ID 配置**页面上，为应用程序选择适当的设置。然后选择 **Save**（保存）。

   1. 选择 **Continue**（继续）。

1. 在 **Confirm your App ID**（确认您的应用程序 ID）页面上，选择 **Register**（注册）。

1. 如果要将 Sign in with Apple 与本机 iOS 应用程序集成，请继续执行步骤 10。步骤 11 适用于您希望与 Sign in with Apple JS 集成的应用程序。

1. 在标**识符**页面上，选择**应用程序 IDs**菜单，然后选择**服务 IDs**。选择 **\$1** 图标。

1. 在 “**注册新标识符**” 页上，选择 “**服务**” IDs，然后选择 “**继续**”。

1. 在 **Register an Services ID**（注册服务 ID）页面上，执行以下操作：

   1. 在 **Description**（描述）下方，键入描述。

   1. 在 **Identifier**（标识符）下方，键入标识符。记下服务 ID，因为您需要此值才能将 Apple 配置为身份池中的提供商。

   1. 选择 **Sign In with Apple**（使用苹果账号登录），然后选择 **Configure**（配置）。

   1. 在 **Web Authentication Configuration**（Web 身份验证配置）页面上，选择 **Primary App ID**（主应用程序 ID）。在 “**网站**” 下 URLs，选择 **\$1** 图标。对于 **Domains and Subdomains**（域和子域），输入应用程序的域名。在 R **eturn 中 URLs，**输入回传 URL，在用户通过 “使用 Apple 登录” 进行身份验证后，授权会将用户重定向到该网址。

   1. 选择**下一步**。

   1. 选择 **Continue**（继续），然后选择 **Register**（注册）。

1. 在左侧导航窗格中，选择 **Keys**（密钥）。

1. 在 **Keys**（密钥）页面上，选择 **\$1** 图标。

1. 在 **Register a New Key**（注册新密钥）页面上，执行以下操作：

   1. 在 **Key Name**（密钥名称）下方，键入密钥名称。

   1. 选择 **Sign In with Apple**，然后选择 **Configure**（配置）。

   1. 在 **Configure Key**（配置密钥）页面上，选择 **Primary App ID**（主应用程序 ID），然后选择 **Save**（保存）。

   1. 选择 **Continue**（继续），然后选择 **Register**（注册）。

**注意**  
要将 Sign in with Apple 与本机 iOS 应用程序集成，请参阅[通过 Sign in with Apple 实施用户身份验证](https://developer.apple.com/documentation/authenticationservices/implementing-user-authentication-with-sign-in-with-apple)。  
要在本机 iOS 以外的平台中集成 Sign in with Apple（使用苹果账号登录），请参阅[使用 Apple JS 登录](https://developer.apple.com/documentation/signinwithapplejs/)。

## 在 Amazon Cognito 联合身份控制台中配置外部提供商
<a name="login-with-apple-configure-provider"></a>

使用以下过程可以配置外部提供商。

**添加通过 Apple 登录身份提供者（IdP）**

1. 从 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)中选择**身份池**。选择身份池。

1. 选择**用户访问**选项卡。

1. 选择**添加身份提供者**。

1. 选择**通过 Apple 登录**。

1. 输入你使用 [Apple 开发者](https://developer.apple.com)创建的 OAuth 项目的**服务 ID**。有关更多信息，请参阅*通过 Apple 登录文档*中的[使用通过 Apple 登录对用户进行身份验证](https://developer.apple.com/documentation/signinwithapple/authenticating-users-with-sign-in-with-apple)。

1. 要设置 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时请求的角色，请配置**角色设置**。

   1. 您可以为该 IdP 中的用户分配您在配置**经过身份验证的角色**时设置的**原定设置角色**，也可以**使用规则选择角色**。

     1. 如果您选择**使用规则选择角色**，请输入用户身份验证中的来源**声明**、您要用来与声明进行比较的**运算符**、导致与该角色选择匹配的**值**，以及当**角色分配**匹配时要分配的**角色**。选择**添加其他**，以根据不同的条件创建其他规则。

     1. 选择**角色解析**。当用户的声明与您的规则不匹配时，您可以拒绝凭证或为**经过身份验证的角色**颁发凭证。

1. 要更改 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时分配的主体标签，请配置**访问控制属性**。

   1. 如果不应用主体标签，请选择**非活动**。

   1. 要基于 `sub` 和 `aud` 声明应用主体标签，请选择**使用原定设置映射**。

   1. 要为主体标签创建自己的自定义属性模式，请选择**使用自定义映射**。然后，对于您要在标签中表示的每个**声明**，输入要从该声明中获取的**标签键**。

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

## 在 Amazon Cognito 联合身份 CLI 中以 Sign in with Apple 作为提供商的示例
<a name="sign-in-with-apple-cli-examples"></a>

此示例创建一个名为 `MyIdentityPool` 的身份池，并使用 Sign in with Apple（使用苹果账号登录）作为 IdP。

`aws cognito-identity create-identity-pool --identity-pool-name MyIdentityPool --supported-login-providers appleid.apple.com="sameple.apple.clientid"`

 有关更多信息，请参阅[创建身份池](https://docs.aws.amazon.com/cli/latest/reference/cognito-identity/create-identity-pool.html) 

**生成 Amazon Cognito 身份 ID**  
 此示例生成（或检索）Amazon Cognito ID。这是一个公有 API，因此您不需要任何凭证即可调用此 API。

`aws cognito-identity get-id --identity-pool-id SampleIdentityPoolId --logins appleid.apple.com="SignInWithAppleIdToken"`

有关更多信息，请参阅 [get-id](https://docs.aws.amazon.com/cli/latest/reference/cognito-identity/get-id.html)。

**获取 Amazon Cognito 身份 ID 的凭证**  
此示例返回用于提供的身份 ID 和 Sign in with Apple 登录的凭证。这是一个公有 API，因此您不需要任何凭证即可调用此 API。

`aws cognito-identity get-credentials-for-identity --identity-id SampleIdentityId --logins appleid.apple.com="SignInWithAppleIdToken" `

有关更多信息，请参阅 [get-credentials-for-identity](https://docs.aws.amazon.com/cli/latest/reference/cognito-identity/get-credentials-for-identity.html)。

## 使用 Sign in with Apple：Android
<a name="set-up-apple-1.android"></a>

Apple 不提供支持 Sign in with Apple for Android 的开发工具包。您可以改为在 Web 视图中使用 Web 流。
+ 要在应用程序中配置 Sign in with Apple，请按照 Apple 文档中的[配置您的 Web 页面以使用 Sign in with Apple](https://developer.apple.com/documentation/signinwithapple/configuring-your-webpage-for-sign-in-with-apple) 操作。
+ 要将**通过 Apple 登录**按钮添加到 Android 用户界面，请按照 Apple 文档中的[在网页上显示“通过 Apple 登录”按钮](https://developer.apple.com/documentation/signinwithapple/displaying-sign-in-with-apple-buttons-on-the-web)操作。
+ 要使用 Sign in with Apple（使用苹果账号登录）安全地对用户进行身份验证，请按照 Apple 文档中的[使用 Sign in with Apple（使用苹果账号登录）对用户进行身份验证](https://developer.apple.com/documentation/signinwithapple/authenticating-users-with-sign-in-with-apple)操作。

Sign in with Apple 使用会话对象跟踪其状态。Amazon Cognito 使用此会话对象中的 ID 令牌对用户进行身份验证，生成唯一标识符，并在需要时授予用户访问其他 AWS 资源的权限。

```
@Override
public void onSuccess(Bundle response) {
    String token = response.getString("id_token");
    Map<String, String> logins = new HashMap<String, String>();
    logins.put("appleid.apple.com", token);
    credentialsProvider.setLogins(logins);
}
```

## 使用 Sign in with Apple：iOS - Objective-C
<a name="set-up-apple-1.ios-objc"></a>

Apple 为原生 iOS 应用程序中的 Sign in with Apple 提供了开发工具包支持。要在本机 iOS 设备中使用 Sign in with Apple 实施用户身份验证，请按照 Apple 文档中的[使用 Sign in with Apple 实施用户身份验证](https://developer.apple.com/documentation/authenticationservices/implementing-user-authentication-with-sign-in-with-apple)操作。

Amazon Cognito 使用 ID 令牌对用户进行身份验证，生成唯一标识符，并在需要时授予用户访问其他 AWS 资源的权限。

```
(void)finishedWithAuth: (ASAuthorizationAppleIDCredential *)auth error: (NSError *) error {
        NSString *idToken = [ASAuthorizationAppleIDCredential objectForKey:@"identityToken"];
        credentialsProvider.logins = @{ "appleid.apple.com": idToken };
    }
```

## 所用 Sign in with Apple：iOS - Swift
<a name="set-up-apple-1.ios-swift"></a>

Apple 为原生 iOS 应用程序中的 Sign in with Apple 提供了开发工具包支持。要在本机 iOS 设备中使用 Sign in with Apple 实施用户身份验证，请按照 Apple 文档中的[使用 Sign in with Apple 实施用户身份验证](https://developer.apple.com/documentation/authenticationservices/implementing-user-authentication-with-sign-in-with-apple)操作。

Amazon Cognito 使用 ID 令牌对用户进行身份验证，生成唯一标识符，并在需要时授予用户访问其他 AWS 资源的权限。

有关如何在 iOS 中设置 Sign in with Apple（使用苹果账号登录）的更多信息，请参阅[设置 Sign in with Apple（使用苹果账号登录）](https://docs.amplify.aws/sdk/auth/federated-identities/q/platform/ios#set-up-sign-in-with-apple)

```
func finishedWithAuth(auth: ASAuthorizationAppleIDCredential!, error: NSError!) {
    if error != nil {
      print(error.localizedDescription)
    }
    else {
      let idToken = auth.identityToken,
      credentialsProvider.logins = ["appleid.apple.com": idToken!]
    }
}
```

## 使用 “通过 Apple 登录”： JavaScript
<a name="set-up-apple-1.javascript"></a>

苹果不提供支持 “用苹果登录” 的 SDK JavaScript。您可以改为在 Web 视图中使用 Web 流。
+ 要在应用程序中配置 Sign in with Apple，请按照 Apple 文档中的[配置您的 Web 页面以使用 Sign in with Apple](https://developer.apple.com/documentation/signinwithapple/configuring-your-webpage-for-sign-in-with-apple) 操作。
+ 要在 JavaScript 用户界面**中添加 “使用 Apple 登**[录” 按钮，请按照 Apple 文档中的在网页上显示 “使用 Apple 登录” 按钮](https://developer.apple.com/documentation/signinwithapple/displaying-sign-in-with-apple-buttons-on-the-web)进行操作。
+ 要使用 Sign in with Apple（使用苹果账号登录）安全地对用户进行身份验证，请按照 Apple 文档中的[使用 Sign in with Apple（使用苹果账号登录）对用户进行身份验证](https://developer.apple.com/documentation/signinwithapple/authenticating-users-with-sign-in-with-apple)操作。

Sign in with Apple 使用会话对象跟踪其状态。Amazon Cognito 使用此会话对象中的 ID 令牌对用户进行身份验证，生成唯一标识符，并在需要时授予用户访问其他 AWS 资源的权限。

```
function signinCallback(authResult) {
     // Add the apple's id token to the Amazon Cognito credentials login map.
     AWS.config.credentials = new AWS.CognitoIdentityCredentials({
        IdentityPoolId: 'IDENTITY_POOL_ID',
        Logins: {
           'appleid.apple.com': authResult['id_token']
        }
     });

     // Obtain AWS credentials
     AWS.config.credentials.get(function(){
        // Access AWS resources here.
     });
}
```

# 设置 OIDC 提供者作为身份池 IdP
<a name="open-id"></a>

[OpenID Connect](http://openid.net/connect/) 是许多登录提供程序支持的身份验证开放标准。借助 Amazon Cognito，您可以将身份与您通过 [AWS Identity and Access Management](https://aws.amazon.com/iam/) 配置的 OpenID Connect 提供者关联在一起。

**添加 OpenID Connect 提供商**

有关如何创建 OpenID Connect 提供者的信息，请参阅《AWS Identity and Access Management 用户指南》**中的[创建 OpenID Connect（OIDC）身份提供者](https://docs.aws.amazon.com/IAM/latest/UserGuide/identity-providers-oidc.html)。

**将提供商与 Amazon Cognito 关联**

**添加 OIDC 身份提供者（IdP）**

1. 从 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)中选择**身份池**。选择身份池。

1. 选择**用户访问**选项卡。

1. 选择**添加身份提供者**。

1. 选择 **OpenID Connect（OIDC）**。

1. 从您的 IAM 中选择一个 **OIDC 身份提供商** IdPs 。 AWS 账户如果您想添加新的 SAML 提供者，请选择**创建新的提供者**以导航到 IAM 控制台。

1. 要设置 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时请求的角色，请配置**角色设置**。

   1. 您可以为该 IdP 中的用户分配您在配置**经过身份验证的角色**时设置的**原定设置角色**，也可以**使用规则选择角色**。

     1. 如果您选择**使用规则选择角色**，请输入用户身份验证中的来源**声明**、您要用来与声明进行比较的**运算符**、导致与该角色选择匹配的**值**，以及当**角色分配**匹配时要分配的**角色**。选择**添加其他**，以根据不同的条件创建其他规则。

     1. 选择**角色解析**。当用户的声明与您的规则不匹配时，您可以拒绝凭证或为**经过身份验证的角色**颁发凭证。

1. 要更改 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时分配的主体标签，请配置**访问控制属性**。

   1. 如果不应用主体标签，请选择**非活动**。

   1. 要基于 `sub` 和 `aud` 声明应用主体标签，请选择**使用原定设置映射**。

   1. 要为主体标签创建自己的自定义属性模式，请选择**使用自定义映射**。然后，对于您要在标签中表示的每个**声明**，输入要从该声明中获取的**标签键**。

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

您可以将多个 OpenID Connect 提供商与一个身份池关联。

**使用 OpenID Connect**

请参阅提供商的文档，了解如何登录并接收 ID 令牌。

拥有令牌后，将此令牌添加到登录映射。使用提供程序的 URI 作为密钥。

**验证 OpenID Connect 令牌**

首次与 Amazon Cognito 集成时，您可能会收到 `InvalidToken` 异常。务必要了解 Amazon Cognito 如何验证 OpenID Connect (OIDC) 令牌。

**注意**  
如此处所述 ([https://tools.ietf.org/html/rfc7523](https://tools.ietf.org/html/rfc7523))，Amazon Cognito 提供 5 分钟的宽限期来处理系统之间的任何时钟偏差。

1. `iss` 参数必须与登录映射使用的密钥匹配（如 login.provider.com）。

1. 签名必须有效。签名必须可通过 RSA 公有密钥进行验证。
**注意**  
身份池会将 OIDC IdP 签名密钥的缓存短时间保存。如果您的提供商更改了签名密钥，则在此缓存刷新之前，Amazon Cognito 可能会返回 `NoKeyFound` 错误。如果您遇到此错误，请等待大约十分钟，让您的身份池刷新签名密钥。

1. 证书公钥的指纹与您在创建 OIDC 提供程序时在 IAM 中设置的指纹相匹配。

1. 如果存在该`azp`参数，请根据您的 OIDC 提供商 IDs 中列出的客户端检查此值。

1. 如果`azp`参数不存在，请根据您的 OIDC 提供商 IDs 中列出的客户端检查该`aud`参数。

[jwt.io](http://jwt.io/) 网站是用于解码令牌以验证这些值的宝贵资源。

## Android
<a name="set-up-open-id-1.android"></a>

```
Map<String, String> logins = new HashMap<String, String>();
logins.put("login.provider.com", token);
credentialsProvider.setLogins(logins);
```

## iOS - Objective-C
<a name="set-up-open-id-1.ios-objc"></a>

```
credentialsProvider.logins = @{ "login.provider.com": token }
```

## JavaScript
<a name="set-up-open-id-1.javascript"></a>

```
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
 IdentityPoolId: 'IDENTITY_POOL_ID',
 Logins: {
    'login.provider.com': token
 }
});
```

# 设置 SAML 提供者作为身份池 IdP
<a name="saml-identity-provider"></a>

借助 Amazon Cognito 身份池，您可以通过 SAML 2.0 使用身份提供商 (IdPs) 对用户进行身份验证。您可以使用支持 SAML 和 Amazon Cognito 的 IdP，为用户提供简单的引导流程。您支持 SAML 的 IdP 指定了用户可以承担的 IAM 角色。这样，不同的用户可以获得不同的权限集。

## 配置 SAML IdP 身份池
<a name="configure-identity-pool-saml-provider"></a>

以下步骤介绍了如何配置身份池以使用基于 SAML 的 IdP。

**注意**  
在配置身份池以支持 SAML 提供商前，您必须先在 [IAM 控制台](https://console.aws.amazon.com/iam)中配置 SAML IdP。有关更多信息，请参阅 *IAM 用户指南*中的[将第三方 SAML 解决方案提供商与 AWS集成](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_saml_3rd-party.html)。

**添加 SAML 身份提供者（IdP）**

1. 从 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)中选择**身份池**。选择身份池。

1. 选择**用户访问**选项卡。

1. 选择**添加身份提供者**。

1. 选择 **SAML**。

1. 从您 AWS 账户的 IAM 中选择一个 **SAML 身份提供商** IdPs 。如果您想添加新的 SAML 提供者，请选择**创建新的提供者**以导航到 IAM 控制台。

1. 要设置 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时请求的角色，请配置**角色设置**。

   1. 您可以为该 IdP 中的用户分配您在配置**经过身份验证的角色**时设置的**原定设置角色**，也可以**使用规则选择角色**。

     1. 如果您选择**使用规则选择角色**，请输入用户身份验证中的来源**声明**、您要用来与声明进行比较的**运算符**、导致与该角色选择匹配的**值**，以及当**角色分配**匹配时要分配的**角色**。选择**添加其他**，以根据不同的条件创建其他规则。

     1. 选择**角色解析**。当用户的声明与您的规则不匹配时，您可以拒绝凭证或为**经过身份验证的角色**颁发凭证。

1. 要更改 Amazon Cognito 在向通过该提供者进行身份验证的用户颁发凭证时分配的主体标签，请配置**访问控制属性**。

   1. 如果不应用主体标签，请选择**非活动**。

   1. 要基于 `sub` 和 `aud` 声明应用主体标签，请选择**使用原定设置映射**。

   1. 要为主体标签创建自己的自定义属性模式，请选择**使用自定义映射**。然后，对于您要在标签中表示的每个**声明**，输入要从该声明中获取的**标签键**。

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

## 配置 SAML IdP
<a name="configure-your-saml-identity-provider"></a>

创建 SAML 提供程序后，配置 SAML IdP，以在 IdP 和 AWS之间添加信赖方信任。使用 man IdPs y，您可以指定一个 URL，IdP 可以使用该网址从 XML 文档中读取信赖方信息和证书。对于 AWS，你可以使用 [https://signin.aws.amazon.com/static/saml-metadata.xml](https://signin.aws.amazon.com/static/saml-metadata.xml)。下一步是配置来自 IdP 的 SAML 断言响应，以填充所需的声明。 AWS 有关申请配置的详细信息，请参阅[针对身份验证响应配置 SAML 断言](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml_assertions.html)。

如果在 SAML 元数据中，您的 SAML IdP 包含多个签名证书，则在登录时，只要与 SAML 元数据中的任何证书匹配，您的身份池就会确定 SAML 断言有效。

## 使用 SAML 自定义用户角色
<a name="role-customization-saml"></a>

将 SAML 与 Amazon Cognito 身份结合使用时，可针对终端用户自定义角色。Amazon Cognito 只支持对基于 SAML 的 IdP 使用[增强流程](authentication-flow.md)。您无需为身份池指定经过身份验证或未经身份验证的角色，即可使用基于 SAML 的 IdP。`https://aws.amazon.com/SAML/Attributes/Role` 声明属性指定一个或多个逗号分隔的角色和提供商 ARN 对。这些是用户可以担任的角色。您可以配置 SAML IdP 以根据 IdP 提供的用户属性信息填充角色属性。如果您在 SAML 断言中收到多个角色，请在调用 `getCredentialsForIdentity` 时填充可选的 `customRoleArn` 参数。如果 `customRoleArn` 角色与 SAML 断言中的声明中的角色匹配，则用户将承担此角色。

## 使用 SAML IdP 对用户进行身份验证
<a name="authenticate-user-with-saml"></a>

要与基于 SAML 的 IdP 联合，请确定用户启动登录的 URL。 AWS 联盟使用 IDP 发起的登录。在 AD FS 2.0 中，URL 采用 `https://<fqdn>/adfs/ls/IdpInitiatedSignOn.aspx?loginToRp=urn:amazon:webservices` 格式。

要在 Amazon Cognito 中添加对 SAML IdP 的支持，请首先使用 SAML 身份提供商从 iOS 或 Android 应用程序对用户进行身份验证。您用于与 SAML IdP 集成和向其进行身份验证的代码特定于 SAML 提供商。在对用户进行身份验证后，您可以使用 Amazon Cognito APIs 向亚马逊 Cognito Identity 提供生成的 SAML 断言。

您无法在身份池 API 请求的 `Logins` 映射中重复或*重放* SAML 断言。重放的 SAML 断言的断言 ID 与早期 API 请求的 ID 重复。可以在`Logins`地图中接受 SAML 断言的 API 操作包括[GetId](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetId.html)、[GetCredentialsForIdentity[GetOpenIdToken](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetOpenIdToken.html)](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetCredentialsForIdentity.html)、和。[GetOpenIDTokenForDeveloperIdentity](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetOpenIdTokenForDeveloperIdentity.html)您可以在身份池身份验证流程中对于每个 API 请求重放 SAML 断言 ID 一次。例如，您可以在 `GetId` 请求和后续 `GetCredentialsForIdentity` 请求中提供相同的 SAML 断言，但不能在第二个 `GetId` 请求中提供相同的 SAML 断言。

# 经开发人员验证的身份
<a name="developer-authenticated-identities"></a>

除了通过 [将 Facebook 设置为身份池 IdP](facebook.md)、[将 Google 设置为身份池 IdP](google.md)、[设置 Login with Amazon 作为身份池 IdP](amazon.md) 和 [使用 Apple 作为身份池 IdP 来设置登录](apple.md) 的 Web 身份联合验证之外，Amazon Cognito 还支持经开发人员验证的身份。使用经过开发人员身份验证的身份，您可以通过自己的现有身份验证流程注册和验证用户，同时仍可以使用 Amazon Cognito 同步用户数据和访问资源。 AWS 使用经开发人员验证的身份涉及最终用户设备、身份验证后端和 Amazon Cognito 之间的交互。有关更多详细信息，请参阅博客中的[了解 Amazon Cognito 身份验证第 2 部分：经过开发人员身份验证的 AWS 身份](https://aws.amazon.com/blogs/mobile/understanding-amazon-cognito-authentication-part-2-developer-authenticated-identities/)。

## 了解身份验证流程
<a name="understanding-the-authentication-flow"></a>

[GetOpenIdTokenForDeveloperIdentity](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetOpenIdTokenForDeveloperIdentity.html)API 操作可以为增强身份验证和基本身份验证启动开发者身份验证。此 API 使用管理凭证对请求进行身份验证。`Logins` 映射是身份池开发人员提供者的名称，例如与自定义标识符配对的 `login.mydevprovider`。

示例：

```
"Logins": {
        "login.mydevprovider": "my developer identifier"
    }
```

**增强型身份验证**

使用包含令牌名称`cognito-identity.amazonaws.com`和值`Logins`的地图调用 [GetCredentialsForIdentity](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetCredentialsForIdentity.html)API 操作`GetOpenIdTokenForDeveloperIdentity`。

示例：

```
"Logins": {
        "cognito-identity.amazonaws.com": "eyJra12345EXAMPLE"
    }
```

`GetCredentialsForIdentity` 使用经开发人员验证的身份，它会返回身份池中默认经过身份验证的角色的临时凭证。

**基本身份验证**

调用 [AssumeRoleWithWebIdentity](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html)API 操作并请求已[定义适当信任关系`RoleArn`的任何 IAM 角色的](iam-roles.md#role-trust-and-permissions)。将 `WebIdentityToken` 的值设置为从 `GetOpenIdTokenForDeveloperIdentity` 获取令牌。

要了解经开发人员验证的身份的身份验证流程以及该流程与外部提供者身份验证流程有何不同，请参阅[身份池身份验证流程](authentication-flow.md)。

## 定义开发人员提供商名称并将其与身份池关联
<a name="associate-developer-provider"></a>

要使用经开发人员验证的身份，您需要与开发人员提供者关联的身份池。为此，请按照以下步骤操作：

**添加自定义开发人员提供者**

1. 从 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)中选择**身份池**。选择身份池。

1. 选择**用户访问**选项卡。

1. 选择**添加身份提供者**。

1. 选择**自定义开发人员提供者**。

1. 输入**开发人员提供者名称**。添加开发人员提供者后，无法更改或删除它。

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

注意：一旦设置提供商名称，便无法进行更改。

## 实施身份提供商
<a name="implement-an-identity-provider"></a>

### Android
<a name="implement-id-provider-1.android"></a>

要使用经开发人员验证的身份，请实施自己的身份提供者类，该类可扩展 `AWSAbstractCognitoIdentityProvider`。您的身份提供者类应返回包含令牌作为属性的响应对象。

以下是身份提供者的基本示例。

```
public class DeveloperAuthenticationProvider extends AWSAbstractCognitoDeveloperIdentityProvider {

  private static final String developerProvider = "<Developer_provider_name>";

  public DeveloperAuthenticationProvider(String accountId, String identityPoolId, Regions region) {
    super(accountId, identityPoolId, region);
    // Initialize any other objects needed here.
  }

  // Return the developer provider name which you choose while setting up the
  // identity pool in the &COG; Console

  @Override
  public String getProviderName() {
    return developerProvider;
  }

  // Use the refresh method to communicate with your backend to get an
  // identityId and token.

  @Override
  public String refresh() {

    // Override the existing token
    setToken(null);

    // Get the identityId and token by making a call to your backend
    // (Call to your backend)

    // Call the update method with updated identityId and token to make sure
    // these are ready to be used from Credentials Provider.

    update(identityId, token);
    return token;

  }

  // If the app has a valid identityId return it, otherwise get a valid
  // identityId from your backend.

  @Override
  public String getIdentityId() {

    // Load the identityId from the cache
    identityId = cachedIdentityId;

    if (identityId == null) {
       // Call to your backend
    } else {
       return identityId;
    }

  }
}
```

要使用此身份提供商，您必须将其传递到 `CognitoCachingCredentialsProvider`。示例如下：

```
DeveloperAuthenticationProvider developerProvider = new DeveloperAuthenticationProvider( null, "IDENTITYPOOLID", context, Regions.USEAST1);
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider( context, developerProvider, Regions.USEAST1);
```

### iOS – objective-C
<a name="implement-id-provider-1.ios-objc"></a>

要使用经开发人员验证的身份，请实施自己的身份提供者类，该类可扩展 [AWSCognitoCredentialsProviderHelper](https://github.com/aws-amplify/aws-sdk-ios)。您的身份提供者类应返回包含令牌作为属性的响应对象。

```
@implementation DeveloperAuthenticatedIdentityProvider
/*
 * Use the token method to communicate with your backend to get an
 * identityId and token.
 */

- (AWSTask <NSString*> *) token {
    //Write code to call your backend:
    //Pass username/password to backend or some sort of token to authenticate user
    //If successful, from backend call getOpenIdTokenForDeveloperIdentity with logins map 
    //containing "your.provider.name":"enduser.username"
    //Return the identity id and token to client
    //You can use AWSTaskCompletionSource to do this asynchronously

    // Set the identity id and return the token
    self.identityId = response.identityId;
    return [AWSTask taskWithResult:response.token];
}

@end
```

要使用此身份提供者，请将其传递到 `AWSCognitoCredentialsProvider`，如下例所示：

```
DeveloperAuthenticatedIdentityProvider * devAuth = [[DeveloperAuthenticatedIdentityProvider alloc] initWithRegionType:AWSRegionYOUR_IDENTITY_POOL_REGION 
                                         identityPoolId:@"YOUR_IDENTITY_POOL_ID"
                                        useEnhancedFlow:YES
                                identityProviderManager:nil];
AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc]
                                                          initWithRegionType:AWSRegionYOUR_IDENTITY_POOL_REGION
                                                          identityProvider:devAuth];
```

如果您想同时支持未经身份验证的身份和经开发人员验证的身份，请在 `logins` 实施中覆盖 `AWSCognitoCredentialsProviderHelper` 方法。

```
- (AWSTask<NSDictionary<NSString *, NSString *> *> *)logins {
    if(/*logic to determine if user is unauthenticated*/) {
        return [AWSTask taskWithResult:nil];
    }else{
        return [super logins];
    }
}
```

如果您想支持经开发人员验证的身份和社交提供者，您必须管理在 `AWSCognitoCredentialsProviderHelper` 的 `logins` 实施中谁是当前的提供者。

```
- (AWSTask<NSDictionary<NSString *, NSString *> *> *)logins {
    if(/*logic to determine if user is unauthenticated*/) {
        return [AWSTask taskWithResult:nil];
    }else if (/*logic to determine if user is Facebook*/){
        return [AWSTask taskWithResult: @{ AWSIdentityProviderFacebook : [FBSDKAccessToken currentAccessToken] }];
    }else {
        return [super logins];
    }
}
```

### iOS – swift
<a name="implement-id-provider-1.ios-swift"></a>

要使用经开发人员验证的身份，请实施自己的身份提供者类，该类可扩展 [AWSCognitoCredentialsProviderHelper](https://github.com/aws-amplify/aws-sdk-ios)。您的身份提供者类应返回包含令牌作为属性的响应对象。

```
import AWSCore
/*
 * Use the token method to communicate with your backend to get an
 * identityId and token.
 */
class DeveloperAuthenticatedIdentityProvider : AWSCognitoCredentialsProviderHelper {
    override func token() -> AWSTask<NSString> {
    //Write code to call your backend:
    //pass username/password to backend or some sort of token to authenticate user, if successful, 
    //from backend call getOpenIdTokenForDeveloperIdentity with logins map containing "your.provider.name":"enduser.username"
    //return the identity id and token to client
    //You can use AWSTaskCompletionSource to do this asynchronously

    // Set the identity id and return the token
    self.identityId = resultFromAbove.identityId
    return AWSTask(result: resultFromAbove.token)
}
```

要使用此身份提供者，请将其传递到 `AWSCognitoCredentialsProvider`，如下例所示：

```
let devAuth = DeveloperAuthenticatedIdentityProvider(regionType: .YOUR_IDENTITY_POOL_REGION, identityPoolId: "YOUR_IDENTITY_POOL_ID", useEnhancedFlow: true, identityProviderManager:nil)
let credentialsProvider = AWSCognitoCredentialsProvider(regionType: .YOUR_IDENTITY_POOL_REGION, identityProvider:devAuth)
let configuration = AWSServiceConfiguration(region: .YOUR_IDENTITY_POOL_REGION, credentialsProvider:credentialsProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
```

如果您想同时支持未经身份验证的身份和经开发人员验证的身份，请在 `logins` 实施中覆盖 `AWSCognitoCredentialsProviderHelper` 方法。

```
override func logins () -> AWSTask<NSDictionary> {
    if(/*logic to determine if user is unauthenticated*/) {
        return AWSTask(result:nil)
    }else {
        return super.logins()
    }
}
```

如果您想支持经开发人员验证的身份和社交提供者，您必须管理在 `AWSCognitoCredentialsProviderHelper` 的 `logins` 实施中谁是当前的提供者。

```
override func logins () -> AWSTask<NSDictionary> {
    if(/*logic to determine if user is unauthenticated*/) {
        return AWSTask(result:nil)
    }else if (/*logic to determine if user is Facebook*/){
        if let token = AccessToken.current?.authenticationToken {
            return AWSTask(result: [AWSIdentityProviderFacebook:token])
        }
        return AWSTask(error:NSError(domain: "Facebook Login", code: -1 , userInfo: ["Facebook" : "No current Facebook access token"]))
    }else {
        return super.logins()
    }
}
```

### JavaScript
<a name="implement-id-provider-1.javascript"></a>

从后端获取身份 ID 和会话令牌后，您要将它们传递到 `AWS.CognitoIdentityCredentials` 提供者。以下为示例。

```
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
   IdentityPoolId: 'IDENTITY_POOL_ID',
   IdentityId: 'IDENTITY_ID_RETURNED_FROM_YOUR_PROVIDER',
   Logins: {
      'cognito-identity.amazonaws.com': 'TOKEN_RETURNED_FROM_YOUR_PROVIDER'
   }
});
```

### Unity
<a name="implement-id-provider-1.unity"></a>

要使用经开发人员验证的身份，您必须扩展 `CognitoAWSCredentials` 并覆盖 `RefreshIdentity` 方法，以从后端检索用户身份 ID 和令牌，并将它们返回。下面是可通过“example.com”联系假想后端的身份提供者的简单示例：

```
using UnityEngine;
using System.Collections;
using Amazon.CognitoIdentity;
using System.Collections.Generic;
using ThirdParty.Json.LitJson;
using System;
using System.Threading;

public class DeveloperAuthenticatedCredentials : CognitoAWSCredentials
{
    const string PROVIDER_NAME = "example.com";
    const string IDENTITY_POOL = "IDENTITY_POOL_ID";
    static readonly RegionEndpoint REGION = RegionEndpoint.USEast1;

    private string login = null;

    public DeveloperAuthenticatedCredentials(string loginAlias)
        : base(IDENTITY_POOL, REGION)
    {
        login = loginAlias;
    }

    protected override IdentityState RefreshIdentity()
    {
        IdentityState state = null;
        ManualResetEvent waitLock = new ManualResetEvent(false);
        MainThreadDispatcher.ExecuteCoroutineOnMainThread(ContactProvider((s) =>
        {
            state = s;
            waitLock.Set();
        }));
        waitLock.WaitOne();
        return state;
    }

    IEnumerator ContactProvider(Action<IdentityState> callback)
    {
        WWW www = new WWW("http://example.com/?username="+login);
        yield return www;
        string response = www.text;

        JsonData json = JsonMapper.ToObject(response);

        //The backend has to send us back an Identity and a OpenID token
        string identityId = json["IdentityId"].ToString();
        string token = json["Token"].ToString();

        IdentityState state = new IdentityState(identityId, PROVIDER_NAME, token, false);
        callback(state);
    }
}
```

上面的代码使用线程调度程序对象调用协同程序。如果您在项目中无法执行上述操作，您可以在场景中使用以下脚本：

```
using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class MainThreadDispatcher : MonoBehaviour
{
    static Queue<IEnumerator> _coroutineQueue = new Queue<IEnumerator>();
    static object _lock = new object();

    public void Update()
    {
        while (_coroutineQueue.Count > 0)
        {
            StartCoroutine(_coroutineQueue.Dequeue());
        }
    }

    public static void ExecuteCoroutineOnMainThread(IEnumerator coroutine)
    {
        lock (_lock) {
            _coroutineQueue.Enqueue(coroutine);
        }
    }
}
```

### Xamarin
<a name="implement-id-provider-1.xamarin"></a>

要使用经开发人员验证的身份，您必须扩展 `CognitoAWSCredentials` 并覆盖 `RefreshIdentity` 方法，以从后端检索用户身份 ID 和令牌，并将它们返回。下面是可通过“example.com”联系假想后端的身份提供者的基本示例：

```
public class DeveloperAuthenticatedCredentials : CognitoAWSCredentials
{
    const string PROVIDER_NAME = "example.com";
    const string IDENTITY_POOL = "IDENTITY_POOL_ID";
    static readonly RegionEndpoint REGION = RegionEndpoint.USEast1;
    private string login = null;

    public DeveloperAuthenticatedCredentials(string loginAlias)
        : base(IDENTITY_POOL, REGION)
    {
        login = loginAlias;
    }

    protected override async Task<IdentityState> RefreshIdentityAsync()
    {
        IdentityState state = null;
        //get your identity and set the state
        return state;
    }
}
```

## 更新登录映射（仅限 Android 和 iOS）
<a name="updating-the-logins-map"></a>

### Android
<a name="updating-logins-map-1.android"></a>

使用身份验证系统成功对用户进行身份验证后，请使用开发人员提供者名称和开发人员用户标识符更新登录映射。此标识符是一个字母数字字符串，可在身份验证系统中唯一标识用户。请确保在更新登录映射后调用 `refresh` 方法，因为 `identityId` 可能已更改：

```
HashMap<String, String> loginsMap = new HashMap<String, String>();
loginsMap.put(developerAuthenticationProvider.getProviderName(), developerUserIdentifier);

credentialsProvider.setLogins(loginsMap);
credentialsProvider.refresh();
```

### iOS – objective-C
<a name="updating-logins-map-1.ios-objc"></a>

如果没有凭证或者凭证已过期，则 iOS 开发工具包仅调用 `logins` 方法，以获取最新登录映射。如果您要强制 SDK 获取新的凭证（例如，最终用户从未经身份验证变为经过身份验证并且您想要经过身份验证的用户的凭证），则对 `credentialsProvider` 调用 `clearCredentials`。

```
[credentialsProvider clearCredentials];
```

### iOS – swift
<a name="updating-logins-map-1.ios-swift"></a>

如果没有凭证或者凭证已过期，则 iOS 开发工具包仅调用 `logins` 方法，以获取最新登录映射。如果您要强制开发工具包获取新的凭证 (例如，最终用户从未经身份验证变为经过身份验证并且您想要经过身份验证的用户的凭证)，则在 `clearCredentials` 上调用 `credentialsProvider`。

```
credentialsProvider.clearCredentials()
```

## 获取令牌（服务器端）
<a name="getting-a-token-server-side"></a>

您可以通过调用获取令牌[GetOpenIdTokenForDeveloperIdentity](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetOpenIdTokenForDeveloperIdentity.html)。必须使用 AWS 开发者凭据从您的后端调用此 API。不得从客户端开发工具包调用它。API 接收 Cognito 身份池 ID；包含身份提供者名称作为密钥及标识符作为值的登录映射；以及可选 Cognito 身份 ID（例如，您让一个未经过身份验证的用户变成了经身份验证的用户）。标识符可以是用户的用户名、电子邮件地址或数值。API 通过为用户提供唯一 Cognito ID 及为最终用户提供 OpenID Connect 令牌来响应您的调用。

对于由 `GetOpenIdTokenForDeveloperIdentity` 返回的令牌，您需要注意以下事项：
+ 您可以指定令牌的自定义过期时间，以便缓存。如果您不提供任何自定义过期时间，则令牌的有效期为 15 分钟。
+ 您可以设置的最大令牌持续时间为 24 小时。
+ 请留意延长令牌持续时间所带来的安全方面的问题。如果攻击者获得此令牌，他们可以在令牌有效期内将其交换为最终用户的 AWS 凭证。

以下 Java 代码段显示了如何初始化 Amazon Cognito 客户端，以及如何检索经开发人员验证的身份的令牌。

```
// authenticate your end user as appropriate
// ....

// if authenticated, initialize a cognito client with your AWS developer credentials
AmazonCognitoIdentity identityClient = new AmazonCognitoIdentityClient(
  new BasicAWSCredentials("access_key_id", "secret_access_key")
);

// create a new request to retrieve the token for your end user
GetOpenIdTokenForDeveloperIdentityRequest request =
  new GetOpenIdTokenForDeveloperIdentityRequest();
request.setIdentityPoolId("YOUR_COGNITO_IDENTITY_POOL_ID");

request.setIdentityId("YOUR_COGNITO_IDENTITY_ID"); //optional, set this if your client has an
                                                   //identity ID that you want to link to this 
                                                   //developer account

// set up your logins map with the username of your end user
HashMap<String,String> logins = new HashMap<>();
logins.put("YOUR_IDENTITY_PROVIDER_NAME","YOUR_END_USER_IDENTIFIER");
request.setLogins(logins);

// optionally set token duration (in seconds)
request.setTokenDuration(60 * 15l);
GetOpenIdTokenForDeveloperIdentityResult response =
  identityClient.getOpenIdTokenForDeveloperIdentity(request);

// obtain identity id and token to return to your client
String identityId = response.getIdentityId();
String token = response.getToken();

//code to return identity id and token to client
//...
```

按照上述步骤操作，您应该能够将经开发人员验证的身份集成到应用程序中。如有任何问题或疑问，请随时在我们的[论坛](https://forums.aws.amazon.com/forum.jspa?forumID=173)上发帖。

## 连接到现有社交身份
<a name="connect-to-an-existing-social-identity"></a>

当您使用经开发人员验证的身份时，您必须从后端链接所有提供者。要将自定义身份与用户的社交身份（Login with Amazon、使用 Apple 登录、Facebook 或 Google 登录）关联起来，请在致电[GetOpenIdTokenForDeveloperIdentity](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetOpenIdTokenForDeveloperIdentity.html)时将身份提供者令牌添加到登录地图中。要实现上述目标，当您从客户端开发工具包调用后端来对最终用户进行身份验证时，您还需要传递最终用户的社交提供商令牌。

例如，如果您想将自定义身份链接到 Facebook，在调用 `GetOpenIdTokenForDeveloperIdentity` 时，除了身份提供商标识符之外，您还需要将 Facebook 令牌添加到登录映射。

```
logins.put("YOUR_IDENTITY_PROVIDER_NAME","YOUR_END_USER_IDENTIFIER");
logins.put("graph.facebook.com","END_USERS_FACEBOOK_ACCESSTOKEN");
```

## 支持在提供商之间转换
<a name="supporting-transition-between-providers"></a>

### Android
<a name="support-transition-between-providers-1.android"></a>

您的应用程序可能需要支持未经身份验证的身份或使用公有提供者（Login with Amazon、通过 Apple 登录、Facebook 或 Google）的经过身份验证的身份，以及经开发人员验证的身份。经开发人员验证的身份与其他身份（未经身份验证的身份和使用公共提供者的经过身份验证的身份）的主要区别在于 identityId 和令牌的获取方式。对于其他身份，移动应用程序将直接与 Amazon Cognito 进行交互，而不是与身份验证系统联系。因此，移动应用程序应该能够支持两个不同的流程，具体取决于应用程序用户的选择。对此，您必须对自定义身份提供者做出一些更改。

`refresh` 方法检查登录映射。如果映射不为空并且有带开发人员提供者名称的密钥，请调用您的后端。否则，调用该 getIdentityId方法并返回 null。

```
public String refresh() {

   setToken(null);

   // If the logins map is not empty make a call to your backend
   // to get the token and identityId
   if (getProviderName() != null &&
      !this.loginsMap.isEmpty() &&
      this.loginsMap.containsKey(getProviderName())) {

      /**
       * This is where you would call your backend
       **/

      // now set the returned identity id and token in the provider
      update(identityId, token);
      return token;

   } else {
      // Call getIdentityId method and return null
      this.getIdentityId();
      return null;
   }
}
```

同样，`getIdentityId` 方法也有两个流程，具体取决于登录映射的内容：

```
public String getIdentityId() {

   // Load the identityId from the cache
   identityId = cachedIdentityId;

   if (identityId == null) {

      // If the logins map is not empty make a call to your backend
      // to get the token and identityId

      if (getProviderName() != null && !this.loginsMap.isEmpty()
         && this.loginsMap.containsKey(getProviderName())) {

         /**
           * This is where you would call your backend
          **/

         // now set the returned identity id and token in the provider
         update(identityId, token);
         return token;

      } else {
         // Otherwise call &COG; using getIdentityId of super class
         return super.getIdentityId();
      }

   } else {
      return identityId;
   }

}
```

### iOS – objective-C
<a name="support-transition-between-providers-1.ios-objc"></a>

您的应用程序可能需要支持未经身份验证的身份或使用公有提供者（Login with Amazon、通过 Apple 登录、Facebook 或 Google）的经过身份验证的身份，以及经开发人员验证的身份。为此，请重写该[AWSCognitoCredentialsProviderHelper](https://github.com/aws-amplify/aws-sdk-ios)`logins`方法，以便能够根据当前身份提供者返回正确的登录映射。此示例说明如何能够在未经身份验证的身份、Facebook 和经开发人员验证的身份之间切换。

```
- (AWSTask<NSDictionary<NSString *, NSString *> *> *)logins {
    if(/*logic to determine if user is unauthenticated*/) {
        return [AWSTask taskWithResult:nil];
    }else if (/*logic to determine if user is Facebook*/){
        return [AWSTask taskWithResult: @{ AWSIdentityProviderFacebook : [FBSDKAccessToken currentAccessToken] }];
    }else {
        return [super logins];
    }
}
```

当您从未经身份验证转换为经过身份验证时，您应该调用 `[credentialsProvider clearCredentials];` 以强制开发工具包获取经过身份验证的新凭证。当您在两个经过身份验证的提供者之间切换并且不想将这两个提供者链接起来时（例如，您没有在登录词典中为多个提供者提供令牌），请调用 `[credentialsProvider clearKeychain];`。上述操作将清除凭证和身份，并强制开发工具包获取新的。

### iOS – swift
<a name="support-transition-between-providers-1.ios-swift"></a>

您的应用程序可能需要支持未经身份验证的身份或使用公有提供者（Login with Amazon、通过 Apple 登录、Facebook 或 Google）的经过身份验证的身份，以及经开发人员验证的身份。为此，请重写该[AWSCognitoCredentialsProviderHelper](https://github.com/aws-amplify/aws-sdk-ios)`logins`方法，以便能够根据当前身份提供者返回正确的登录映射。此示例说明如何能够在未经身份验证的身份、Facebook 和经开发人员验证的身份之间切换。

```
override func logins () -> AWSTask<NSDictionary> {
    if(/*logic to determine if user is unauthenticated*/) {
        return AWSTask(result:nil)
    }else if (/*logic to determine if user is Facebook*/){
        if let token = AccessToken.current?.authenticationToken {
            return AWSTask(result: [AWSIdentityProviderFacebook:token])
        }
        return AWSTask(error:NSError(domain: "Facebook Login", code: -1 , userInfo: ["Facebook" : "No current Facebook access token"]))
    }else {
        return super.logins()
    }
}
```

当您从未经身份验证转换为经过身份验证时，您应该调用 `credentialsProvider.clearCredentials()` 以强制开发工具包获取经过身份验证的新凭证。当您在两个经过身份验证的提供商之间切换并且不想将这两个提供商链接起来时 (即，您没有在登录词典中为多个提供商提供令牌)，您应该调用 `credentialsProvider.clearKeychain()`。上述操作将清除凭证和身份，并强制开发工具包获取新的。

### Unity
<a name="support-transition-between-providers-1.unity"></a>

您的应用程序可能需要支持未经身份验证的身份或使用公有提供者（Login with Amazon、通过 Apple 登录、Facebook 或 Google）的经过身份验证的身份，以及经开发人员验证的身份。经开发人员验证的身份与其他身份（未经身份验证的身份和使用公共提供者的经过身份验证的身份）的主要区别在于 identityId 和令牌的获取方式。对于其他身份，移动应用程序将直接与 Amazon Cognito 进行交互，而不是与身份验证系统联系。移动应用程序应该能够支持两个不同的流程，具体取决于应用程序用户的选择。对此，您必须对自定义身份提供商做出一些更改。

在 Unity 中执行此操作的推荐方法是从 AmazonCognitoEnhancedIdentityProvide 而不是扩展您的身份提供商 AbstractCognitoIdentityProvider，并调用父 RefreshAsync 方法而不是您自己的方法，以防用户未使用您自己的后端进行身份验证。如果用户已经过身份验证，则您可以使用之前介绍的相同的流程。

### Xamarin
<a name="support-transition-between-providers-1.xamarin"></a>

您的应用程序可能需要支持未经身份验证的身份或使用公有提供者（Login with Amazon、通过 Apple 登录、Facebook 或 Google）的经过身份验证的身份，以及经开发人员验证的身份。经开发人员验证的身份与其他身份（未经身份验证的身份和使用公共提供者的经过身份验证的身份）的主要区别在于 identityId 和令牌的获取方式。对于其他身份，移动应用程序将直接与 Amazon Cognito 进行交互，而不是与身份验证系统联系。移动应用程序应该能够支持两个不同的流程，具体取决于应用程序用户的选择。对此，您必须对自定义身份提供者做出一些更改。

# 将未经身份验证的用户切换为经过身份验证的用户
<a name="switching-identities"></a>

Amazon Cognito 身份池同时支持经过身份验证的用户和未经身份验证的用户。未经身份验证的用户即使未使用您的任何身份提供商登录，也可以访问您的 AWS 资源（IdPs）。此级别的访问可用于向尚未登录的用户显示内容。即使每个未经身份验证的用户尚未单独登录和经过身份验证，这些用户在身份池中也都具有唯一的身份。

本节介绍了用户如何选择从使用未经身份验证的身份登录切换为使用经过身份验证的身份登录。

## Android
<a name="switching-identities-1.android"></a>

用户能够以未经身份验证的来宾的身份登录您的应用程序。最终，他们可能会决定使用其中一个支持的登录 IdPs。Amazon Cognito 将确保旧身份保留与新身份相同的唯一标识符，并确保配置文件数据自动合并。

应用程序会通过 `IdentityChangedListener` 界面收到配置文件合并的消息。在界面中实施 `identityChanged` 方法以接收这些消息：

```
@override
public void identityChanged(String oldIdentityId, String newIdentityId) {
    // handle the change
}
```

## iOS – objective-C
<a name="switching-identities-1.ios-objc"></a>

用户能够以未经身份验证的来宾的身份登录您的应用程序。最终，他们可能会决定使用其中一个支持的登录 IdPs。Amazon Cognito 将确保旧身份保留与新身份相同的唯一标识符，并确保配置文件数据自动合并。

`NSNotificationCenter` 通知应用程序配置文件合并的消息：

```
[[NSNotificationCenter defaultCenter] addObserver:self
                                      selector:@selector(identityIdDidChange:)
                                      name:AWSCognitoIdentityIdChangedNotification
                                      object:nil];

-(void)identityDidChange:(NSNotification*)notification {
    NSDictionary *userInfo = notification.userInfo;
    NSLog(@"identity changed from %@ to %@",
        [userInfo objectForKey:AWSCognitoNotificationPreviousId],
        [userInfo objectForKey:AWSCognitoNotificationNewId]);
}
```

## iOS – swift
<a name="switching-identities-1.ios-swift"></a>

用户能够以未经身份验证的来宾的身份登录您的应用程序。最终，他们可能会决定使用其中一个支持的登录 IdPs。Amazon Cognito 将确保旧身份保留与新身份相同的唯一标识符，并确保配置文件数据自动合并。

`NSNotificationCenter` 通知应用程序配置文件合并的消息：

```
[NSNotificationCenter.defaultCenter().addObserver(observer: self
   selector:"identityDidChange"
   name:AWSCognitoIdentityIdChangedNotification
   object:nil)

func identityDidChange(notification: NSNotification!) {
  if let userInfo = notification.userInfo as? [String: AnyObject] {
    print("identity changed from: \(userInfo[AWSCognitoNotificationPreviousId])
    to: \(userInfo[AWSCognitoNotificationNewId])")
  }
}
```

## JavaScript
<a name="switching-identities-1.javascript"></a>

### 最初未经身份验证的用户
<a name="switching-identities-1.javascript-unauth"></a>

用户最初通常具有未经身份验证的角色。对于此角色，您可以设置配置对象的凭证属性，而不设置登录属性。在这种情况下，您的默认配置可能如下所示：

```
// set the default config object
var creds = new AWS.CognitoIdentityCredentials({
    IdentityPoolId: 'us-east-1:1699ebc0-7900-4099-b910-2df94f52a030'
});
AWS.config.credentials = creds;
```

### 切换为经过身份验证的用户
<a name="switching-identities-1.javascript-auth"></a>

当未经身份验证的用户登录 IdP 并且您拥有令牌时，您可以通过调用可更新凭证对象和添加登录令牌的自定义函数，来将用户从未经身份验证的用户切换为经过身份验证的用户：

```
// Called when an identity provider has a token for a logged in user
function userLoggedIn(providerName, token) {
    creds.params.Logins = creds.params.Logins || {};
    creds.params.Logins[providerName] = token;

    // Expire credentials to refresh them on the next request
    creds.expired = true;
}
```

您还可以创建 `CognitoIdentityCredentials` 对象。在这种情况下，必须重置任何现有服务对象的凭证属性，以反映更新的凭证配置信息。请参阅[使用全局配置对象](https://docs.aws.amazon.com/sdk-for-javascript/latest/developer-guide/global-config-object.html)。

有关该`CognitoIdentityCredentials`对象的更多信息，请参阅[AWS。 CognitoIdentityCredentials](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityCredentials.html)在 适用于 JavaScript 的 AWS SDK API 参考中。

## Unity
<a name="switching-identities-1.unity"></a>

用户能够以未经身份验证的来宾的身份登录您的应用程序。最终，他们可能会决定使用其中一个支持的登录 IdPs。Amazon Cognito 将确保旧身份保留与新身份相同的唯一标识符，并确保配置文件数据自动合并。

您可以订阅 `IdentityChangedEvent`，以接收配置文件合并的通知：

```
credentialsProvider.IdentityChangedEvent += delegate(object sender, CognitoAWSCredentials.IdentityChangedArgs e)
{
    // handle the change
    Debug.log("Identity changed from " + e.OldIdentityId + " to " + e.NewIdentityId);
};
```

## Xamarin
<a name="switching-identities-1.xamarin"></a>

用户能够以未经身份验证的来宾的身份登录您的应用程序。最终，他们可能会决定使用其中一个支持的登录 IdPs。Amazon Cognito 将确保旧身份保留与新身份相同的唯一标识符，并确保配置文件数据自动合并。

```
credentialsProvider.IdentityChangedEvent += delegate(object sender, CognitoAWSCredentials.IdentityChangedArgs e){
    // handle the change
    Console.WriteLine("Identity changed from " + e.OldIdentityId + " to " + e.NewIdentityId);
};
```