

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

# 将 SAML 身份提供者与用户池配合使用
<a name="cognito-user-pools-saml-idp"></a>

可以选择允许 Web 和移动应用程序用户通过 SAML 身份提供者（IdP）[如 [Microsoft Active Directory 联合身份验证服务（ADFS）](https://msdn.microsoft.com/en-us/library/bb897402.aspx)或 [Shibboleth](http://www.shibboleth.net/)] 登录。您必须选择支持 [SAML 2.0 标准](http://saml.xml.org/saml-specifications)的 SAML IdP。

通过托管登录，Amazon Cognito 可以对本地和第三方 IdP 用户进行身份验证，并发放 JSON 网络令牌 ()。JWTs使用 Amazon Cognito 发放的令牌，您可以将多个身份源整合为适用于所有应用程序的通用 OpenID Connect（OIDC）标准。Amazon Cognito 可以处理来自第三方提供者的 SAML 断言，并将其转换为 SSO 标准。您可以在、通过 AWS CLI或使用 Amazon Cognito 用户池 API 创建和管理 SAML IdP。 AWS 管理控制台要在中创建您的第一个 SAML IdP AWS 管理控制台，请参阅。[在用户池中添加和力 SAML 身份提供者](cognito-user-pools-managing-saml-idp.md)

![\[SAML 登录的身份验证概述\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/scenario-authentication-saml.png)


**注意**  
通过第三方 IdP 登录进行联合身份验证是 Amazon Cognito 用户池的一项特征。Amazon Cognito 身份池（有时称为 Amazon Cognito 联合身份）是一种联合身份验证的实现，您必须在每个身份池中单独进行设置。用户池可以是身份池的第三方 IdP。有关更多信息，请参阅 [Amazon Cognito 身份池](cognito-identity.md)。

## IdP 配置的快速参考
<a name="cognito-user-pools-saml-idp-reference"></a>

您必须配置 SAML IdP，以便接受请求并向用户池发送响应。SAML IdP 的文档将包含相关信息，让您可以了解如何将用户池添加为 SAML 2.0 IdP 的依赖方或应用程序。接下来的文档将提供必须为 SP 实体 ID 和断言使用者服务（ACS）URL 提供的值。用户池 SAML 值快速参考

**SP 实体 ID**  

```
urn:amazon:cognito:sp:us-east-1_EXAMPLE
```

**ACS URL**  

```
https://Your user pool domain/saml2/idpresponse
```

您必须配置用户池来支持您的身份提供者。添加外部 SAML IdP 的大致步骤如下。

1. 从您的 IdP 下载 SAML 元数据，或检索元数据端点的 URL。请参阅[配置第三方 SAML 身份提供者](cognito-user-pools-integrating-3rd-party-saml-providers.md)。

1. 将新的 IdP 添加到用户池。上传 SAML 元数据或提供元数据 URL。请参阅[在用户池中添加和力 SAML 身份提供者](cognito-user-pools-managing-saml-idp.md)。

1. 将 IdP 分配给您的应用程序客户端。请参阅[特定于应用程序的应用程序客户端设置](user-pool-settings-client-apps.md)。

**Topics**
+ [IdP 配置的快速参考](#cognito-user-pools-saml-idp-reference)
+ [关于 Amazon Cognito 用户 IdPs 池中 SAML 的注意事项](cognito-user-pools-saml-idp-things-to-know.md)
+ [SAML 用户名区分大小写](#saml-nameid-case-sensitivity)
+ [配置第三方 SAML 身份提供者](cognito-user-pools-integrating-3rd-party-saml-providers.md)
+ [在用户池中添加和力 SAML 身份提供者](cognito-user-pools-managing-saml-idp.md)
+ [SAML 会话在 Amazon Cognito 用户池中启动](cognito-user-pools-SAML-session-initiation.md)
+ [通过单点注销来注销 SAML 用户](cognito-user-pools-saml-idp-sign-out.md)
+ [SAML 签名和加密](cognito-user-pools-SAML-signing-encryption.md)
+ [SAML 身份提供者名称和标识符](cognito-user-pools-managing-saml-idp-naming.md)

# 关于 Amazon Cognito 用户 IdPs 池中 SAML 的注意事项
<a name="cognito-user-pools-saml-idp-things-to-know"></a>

实施 SAML 2.0 IdP 有一些要求和限制。实施 IdP 时，请参阅此部分。您还将找到一些有用的信息，可用于排查对用户池进行 SAML 联合身份验证期间的错误。

**Amazon Cognito 会为您处理 SAML 断言**  
Amazon Cognito 用户池支持 SAML 2.0 与 POST 绑定端点联合身份验证。这使您的应用程序不必检索或分析 SAML 断言响应，因为用户池直接通过用户代理从 IdP 接收 SAML 响应。您的用户池代表您的应用程序充当服务提供商（SP）。Amazon Cognito 支持 SP 发起和 IdP 发起的单点登录（SSO），如 [SAML V2.0 技术概览](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0-cd-02.html)的第 5.1.2 节和第 5.1.4 节中所述。

**提供有效的 IdP 签名证书**  
在用户池中配置 SAML IdP 时，SAML 提供者元数据中的签名证书不得过期。

**用户池支持多个签名证书**  
如果在 SAML 元数据中，您的 SAML IdP 包含多个签名证书，则在登录时，只要与 SAML 元数据中的任何证书匹配，您的用户池就会确定 SAML 断言有效。每份签名证书的长度不得超过 4096 个字符。

**维护中继状态参数**  
Amazon Cognito 和您的 SAML IdP 使用 `relayState` 参数维护会话信息。  

1. Amazon Cognito 支持大于 80 个字节的 `relayState` 值。虽然 SAML 规范规定 `relayState` 值“长度不得超过 80 个字节”，但目前的行业惯例往往偏离这种行为。因此，拒绝超过 80 个字节的 `relayState` 值将破坏许多标准 SAML 提供商集成。

1. `relayState` 令牌是对 Amazon Cognito 维护的状态信息的不透明引用。Amazon Cognito 不保证 `relayState` 参数的内容。不要解析其内容，以免您的应用程序依赖解析结果。有关更多信息，请参阅 [SAML 2.0 规范](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html)。

**识别 ACS 端点**  
您的 SAML 身份提供者要求您设置断言使用者端点。您的 IdP 使用 SAML 断言将您的用户重定向到此端点。在用户群体域中为您的 SAML 身份提供者中的 SAML 2.0 POST 绑定配置以下端点。  

```
https://Your user pool domain/saml2/idpresponse
With an Amazon Cognito domain:
https://mydomain.auth.us-east-1.amazoncognito.com/saml2/idpresponse
With a custom domain:
https://auth.example.com/saml2/idpresponse
```
有关用户池域的更多信息，请参阅 [配置用户池域](cognito-user-pools-assign-domain.md)。

**没有重播的断言**  
您无法向您的 Amazon Cognito `saml2/idpresponse` 端点重复或*重放* SAML 断言。重放的 SAML 断言的断言 ID 与早期 IdP 响应的 ID 重复。

**用户池 ID 是 SP 实体 ID**  
您必须向 IdP 提供服务提供商（SP）`urn` 中的用户池 ID，也称为*受众 URI* 或 *SP 实体 ID*。用户池的受众 URI 采用以下格式。  

```
urn:amazon:cognito:sp:us-east-1_EXAMPLE
```
您可以在 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)的**用户池概览**下找到用户池 ID。

**映射所有必需属性**  
配置 SAML IdP，为用户池中根据需要设置的任何属性提供值。例如，`email` 是用户池的通用必需属性。在您的用户可以登录之前，SAML IdP 断言必须包含映射到**用户池属性** `email` 的声明。有关属性映射的更多信息，请参阅[将 IdP 属性映射到配置文件和令牌](cognito-user-pools-specifying-attribute-mapping.md)。

**断言格式有特定的要求**  
SAML IdP 必须在 SAML 断言中包括以下声明。  
+ `NameID` 声明。Amazon Cognito 通过 `NameID` 将 SAML 断言与目标用户关联起来。如果 `NameID` 发生变化，Amazon Cognito 会认为这是针对新用户的断言。您在 IdP 配置中设置为 `NameID` 的属性必须具有永久值。要将 SAML 用户分配给用户池中一致的用户配置文件，请根据一个值不变的属性分配您的 `NameID` 声明。

  ```
  <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:persistent">
    carlos
  </saml2:NameID>
  ```

  `urn:oasis:names:tc:SAML:1.1:nameid-format:persistent` 的 IdP `NameID` 声明中的 `Format` 表示您的 IdP 正在传递一个不变的值。Amazon Cognito 不需要这种格式声明，如果您的 IdP 没有指定 `NameID` 声明的格式，则会分配 `urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified` 格式。此行为符合 [SAML 2.0 规范的*复杂类型名称IDType*第 2.2.](https://groups.oasis-open.org/higherlogic/ws/public/download/35711/sstc-saml-core-errata-2.0-wd-06-diff.pdf/latest) 2 节。
+ 一项 `AudienceRestriction` 声明，所具有的 `Audience` 值将您的用户池 SP 实体 ID 设置为响应的目标。

  ```
  <saml:AudienceRestriction>
    <saml:Audience> urn:amazon:cognito:sp:us-east-1_EXAMPLE
  </saml:AudienceRestriction>
  ```
+ 对于 SP 发起的单点登录，`Response` 元素具有原始 SAML 请求 ID 的 `InResponseTo` 值。

  ```
  <saml2p:Response Destination="https://mydomain.auth.us-east-1.amazoncognito.com/saml2/idpresponse" ID="id123" InResponseTo="_dd0a3436-bc64-4679-a0c2-cb4454f04184" IssueInstant="Date-time stamp" Version="2.0" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  ```
**注意**  
IdP 发起的 SAML 断言*不得*包含 `InResponseTo` 值。
+ 一个 `SubjectConfirmationData` 元素，具有用户池 `saml2/idpresponse` 端点的 `Recipient` 值，而对于 SP 发起的 SAML，具有与原始 SAML 请求 ID 匹配的 `InResponseTo` 值。

  ```
  <saml2:SubjectConfirmationData InResponseTo="_dd0a3436-bc64-4679-a0c2-cb4454f04184" NotOnOrAfter="Date-time stamp" Recipient="https://mydomain.auth.us-east-1.amazoncognito.com/saml2/idpresponse"/>
  ```

**SP 发起的登录请求**  
当 [对端点授权](authorization-endpoint.md) 将用户定向到您的 IdP 登录页面时，Amazon Cognito 会在 `HTTP GET` 请求的 URL 参数中包括 *SAML 请求*。SAML 请求包含有关用户池（包括 ACS 端点）的信息。您可以选择对这些请求应用加密签名。

**签署请求和加密响应**  
每个使用 SAML 提供者的用户池都会生成一个非对称密钥对和*签名证书*，以便让 Amazon Cognito 将数字签名分配给 SAML 请求。您配置为支持加密 SAML 响应的每个外部 SAML IdP 都会导致 Amazon Cognito 为该提供者生成新的密钥对和*加密证书*。要查看和下载带有公钥的证书，请在 Amazon Cognito 控制台的**社交和外部提供商**菜单中选择您的 IdP。  
要与来自用户池的 SAML 请求建立信任，可以向 IdP 提供用户池 SAML 2.0 签名证书的副本。如果您未将 IdP 配置为接受已签名的请求，则您的 IdP 可能会忽略您的用户池签署的 SAML 请求。  

1. Amazon Cognito 将数字签名应用于用户传递给 IdP 的 SAML 请求。您的用户池签署所有单点注销（SLO）请求，您可以将用户池配置为签署任何 SAML 外部 IdP 的单点登录（SSO）请求。当您提供证书副本时，您的 IdP 会验证用户的 SAML 请求的完整性。

1. 您的 SAML IdP 可以使用加密证书来加密 SAML 响应。当您配置采用 SAML 加密的 IdP 时，您的 IdP 只能发送加密的响应。

**对非字母数字字符进行编码**  
Amazon Cognito 不接受您的 IdP 作为属性值传递的 4 字节 UTF-8 字符（例如 😐 或 𠮷）。您可以将字符编码为 Base64，将其作为文本传递，然后在应用程序中对其进行解码。  
在以下示例中，将不接受属性声明：  

```
<saml2:Attribute Name="Name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
  <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">😐</saml2:AttributeValue>
</saml2:Attribute>
```
与上述示例不同，将接受以下属性声明：  

```
<saml2:Attribute Name="Name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
  <saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">8J+YkA==</saml2:AttributeValue>
</saml2:Attribute>
```

**元数据端点必须具有有效的传送层安全性**  
如果您在使用 HTTPS 元数据终端节点 URL 创建 SAML IdP `InvalidParameterException` 时看到，例如 “*<metadata endpoint>*从中检索元数据时出错”，请确保元数据端点已正确设置了 SSL，并且存在与之关联的有效的 SSL 证书。有关验证证书的更多信息，请参阅[什么是 SSL/TLS 证书](https://aws.amazon.com/what-is/ssl-certificate/)？ 。

**对于 HTTP 或 HTTPS，元数据端点必须位于标准 TCP 端口上**  
Amazon Cognito 仅接受 HTTP URLs 的标准 TCP 端口 80 和 HTTPS 的 443 上的 SAML 提供商的元数据。作为安全最佳实践，请将 SAML 元数据托管在带有 `https://` 前缀的 TLS 加密 URL 处。以*`http://www.example.com/saml2/metadata.xml`*或 URLs 的格式输入元数据*`https://www.example.com/saml2/metadata.xml`*。Amazon Cognito 控制台 URLs 仅接受带有前`https://`缀的元数据。您也可以使用和配置 IdP 元数据。[CreateIdentityProvider[UpdateIdentityProvider](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateIdentityProvider.html)](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateIdentityProvider.html)

**使用 IdP 发起的 SAML 的应用程序客户端只能使用 SAML 登录**  
当您激活对支持 IdP 启动登录应用程序客户端的 SAML 2.0 IdP 的支持时，您只能向该应用程序客户端添加其他 SAML IdPs 2.0。您无法将用户池中的用户目录*以及*所有非 SAML 外部身份提供者添加到以这种方式配置的应用程序客户端。

**注销响应必须使用 POST 绑定**  
`/saml2/logout` 端点接受 `LogoutResponse` 作为 `HTTP POST` 请求。用户池不接受带有 `HTTP GET` 绑定的注销响应。

**元数据签名证书轮换**  
如果您通过 URL 提供元数据，Amazon Cognito 会将 SAML 元数据缓存长达六个小时。执行任何元数据签名证书轮换时，请将元数据源配置为*同时*发布原始证书和新证书至少六个小时。当 Amazon Cognito 从元数据 URL 刷新缓存时，它会将每个证书视为有效，并且您的 SAML IdP 可以开始使用新证书签名 SAML 断言。在此时间后，您可以从发布的元数据中移除原始证书。

## SAML 用户名区分大小写
<a name="saml-nameid-case-sensitivity"></a>

当联合用户尝试登录时，SAML 身份提供者（IdP）在用户的 SAML 断言中将唯一 `NameId` 传递给 Amazon Cognito。Amazon Cognito 通过其 `NameId` 声明识别 SAML 联合身份用户。无论您的用户池的区分大小写如何设置，当从 SAML IdP 返回的联合用户传递其唯一且区分大小写的 `NameId` 声明时，Amazon Cognito 都会识别该用户。如果您将 `email` 等属性映射到 `NameId`，并且您的用户更改其电子邮件地址，他们将无法登录您的应用程序。

从具有不会改变的值的 IdP 属性映射 SAML 断言中的 `NameId`。

例如，Carlos 在您的不区分大小写的用户池中具有来自 Active Directory 联合身份验证服务 (ADFS) SAML 断言的用户配置文件，该断言传递了`Carlos@example.com` 的 `NameId` 值。下次 Carlos 尝试登录时，您的 ADFS IdP 会传递`carlos@example.com` 的 `NameId` 值。由于 `NameId` 的大小写必须完全匹配，登录不成功。

如果您的用户在其 `NameID` 更改后无法登录，请从您的用户池中删除他们的用户配置文件。Amazon Cognito 将在用户下次登录时创建新的用户配置文件。

**Topics**
+ [IdP 配置的快速参考](#cognito-user-pools-saml-idp-reference)
+ [关于 Amazon Cognito 用户 IdPs 池中 SAML 的注意事项](cognito-user-pools-saml-idp-things-to-know.md)
+ [SAML 用户名区分大小写](#saml-nameid-case-sensitivity)
+ [配置第三方 SAML 身份提供者](cognito-user-pools-integrating-3rd-party-saml-providers.md)
+ [在用户池中添加和力 SAML 身份提供者](cognito-user-pools-managing-saml-idp.md)
+ [SAML 会话在 Amazon Cognito 用户池中启动](cognito-user-pools-SAML-session-initiation.md)
+ [通过单点注销来注销 SAML 用户](cognito-user-pools-saml-idp-sign-out.md)
+ [SAML 签名和加密](cognito-user-pools-SAML-signing-encryption.md)
+ [SAML 身份提供者名称和标识符](cognito-user-pools-managing-saml-idp-naming.md)

# 配置第三方 SAML 身份提供者
<a name="cognito-user-pools-integrating-3rd-party-saml-providers"></a>

如果要将 SAML 身份提供者（IdP）添加到用户池，则必须在 IdP 的管理界面中进行一些配置更新。本节介绍如何格式化您必须提供给 IdP 的值。您还可以了解如何检索用于向用户池标识 IdP 及其 SAML 声明的静态或活动 URL 元数据文档。

要配置第三方 SAML 2.0 身份提供者（IdP）解决方案以使用 Amazon Cognito 用户池的联合身份验证，您必须配置 SAML IdP 以重定向到以下断言使用者服务（ACS）URL：`https://mydomain.auth.us-east-1.amazoncognito.com/saml2/idpresponse`。如果您的用户池具有 Amazon Cognito 域，则可以在 [Amazon Cognito 控制台](https://console.aws.amazon.com/cognito/home)中您的用户池的**域**菜单中找到用户池域路径。

某些 SAML IdPs 要求您在表`urn:amazon:cognito:sp:us-east-1_EXAMPLE`单中`urn`提供（也称为受众 URI 或 SP 实体 ID）。您可以在 Amazon Cognito 控制台的**用户池概览**下找到用户池 ID。

您还必须配置 SAML IdP，以便为用户池中您指定为*必需属性*的任何属性提供值。通常，`email` 是用户池的必需属性，在这种情况下，SAML IdP 必须在其 SAML 断言中提供某种形式的 `email` 声明，且您必须将该声明映射到该提供者的属性。

以下第三方 SAML 2.0 IdP 解决方案的配置信息是开始使用 Amazon Cognito 用户池设置联合身份验证的一个很好的起点。有关最新信息，请直接查阅提供者的文档。

要签署 SAML 请求，必须将 IdP 配置为信任由您的用户池签名证书签署的请求。要接受加密的 SAML 响应，必须将 IdP 配置为对用户池的*所有* SAML 响应进行加密。您的提供者将提供有关配置这些特征的文档。有关 Microsoft 的示例，请参阅[配置 Microsoft Entra SAML 令牌加密](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/howto-saml-token-encryption)。

**注意**  
Amazon Cognito 只需要身份提供者元数据文档。您的提供者还可能提供 SAML 2.0 与 IAM 或 AWS IAM Identity Center联合身份验证的自定义配置信息。要了解如何设置 Amazon Cognito 集成，请查看检索元数据文档的一般说明并管理用户池中的其余配置。


| 解决方案 | 更多信息 | 
| --- | --- | 
| Microsoft Entra ID | [联合身份验证元数据](https://learn.microsoft.com/en-us/entra/identity-platform/federation-metadata) | 
| Okta | [如何下载用于 SAML 应用程序集成的 IdP 元数据和 SAML 签名证书](https://support.okta.com/help/s/article/Location-to-download-Okta-IDP-XML-metadata-for-a-SAML-app-in-the-new-Admin-User-Interface) | 
| Auth0 | [将 Auth0 配置为 SAML 身份提供者](https://auth0.com/docs/authenticate/protocols/saml/saml-sso-integrations/configure-auth0-saml-identity-provider) | 
| Ping 身份 (PingFederate) | [从中导出 SAML 元数据 PingFederate](https://docs.pingidentity.com/integrations/contentful/configuring_single_sign-on/pf_contentful_integration_exporting_saml_metadata_from_pf.html) | 
| JumpCloud | [SAML 配置备注](https://jumpcloud.com/support/saml-configuration-notes) | 
| SecureAuth | [SAML 应用程序集成](https://docs.secureauth.com/2104/en/saml-application-integration.html) | 

# 在用户池中添加和力 SAML 身份提供者
<a name="cognito-user-pools-managing-saml-idp"></a>

将身份提供者配置为与 Amazon Cognito 配合使用后，您可以将其添加到用户池和应用程序客户端。以下步骤演示了如何在 Amazon Cognito 用户池中创建、修改和删除 SAML 提供者。

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

您可以使用 AWS 管理控制台 来创建和删除 SAML 身份提供商 (IdPs)。

在创建 SAML IdP 之前，您必须具有从第三方 IdP 处获得的 SAML 元数据文档。有关如何获取或生成所需的 SAML 元数据文档的说明，请参阅[配置第三方 SAML 身份提供者](cognito-user-pools-integrating-3rd-party-saml-providers.md)。

**在您的用户池中配置 SAML 2.0 IdP**

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

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

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

1. 选择**社交和外部提供商**菜单，然后选择**添加身份提供者**。

1. 选择一个 **SAML** IdP。

1. 输入**提供商名称**。您可以在 `identity_provider` 请求参数中将这个友好名称传递给 [对端点授权](authorization-endpoint.md)。

1. 输入以逗号分隔的 **Identifiers**（标识符）。标识符将告知 Amazon Cognito 应该检查用户登录时输入的电子邮件地址，然后将它们引导到与其域名对应的提供商。

1. 如果您希望 Amazon Cognito 在用户注销时向您的提供商发送已签名的注销请求，请选择 **Add sign-out flow**（添加注销流程）。您必须配置 SAML 2.0 IdP 以向配置托管登录时创建的 `https://mydomain.auth.us-east-1.amazoncognito.com/saml2/logout` 端点发送注销响应。此 `saml2/logout` 端点使用 POST 绑定。
**注意**  
如果选择此选项，且您的 SAML IdP 需要已签署的注销请求，则还必须为您的 SAML IdP 提供来自用户池的签名证书。  
SAML IdP 将处理已签名的注销请求并从 Amazon Cognito 会话中注销您的用户。

1. 选择 **IdP 发起的 SAML 登录**配置。作为一项安全最佳实践，请选择**仅接受 SP 发起的 SAML 断言**。如果您已准备好环境，以便安全地接受未经请求的 SAML 登录会话，请选择**接受 SP 发起和 IdP 发起的 SAML 断言**。有关更多信息，请参阅 [SAML 会话在 Amazon Cognito 用户池中启动](cognito-user-pools-SAML-session-initiation.md)。

1. 选择 **Metadata document source**（元数据文档源）。如果您的 IdP 在公有 URL 上提供 SAML 元数据，则可以选择 **Metadata document URL**（元数据文档 URL），然后输入该公有 URL。否则，请选择 **Upload metadata document**（上载元数据文档），然后选择您之前从提供商下载的元数据文件。
**注意**  
如果您的提供者具有公有端点，建议您输入元数据文档 URL，而不是上传文件。Amazon Cognito 会自动从元数据 URL 刷新元数据。通常，元数据刷新操作每 6 小时执行一次或在元数据过期前执行（以时间较早者为准）。

1. **在 SAML 提供者和用户池之间映射属性**选项将 SAML 提供者属性映射到用户池中的用户配置文件。在属性映射中包含用户池必需属性。

   例如，当您选择 **User pool attribute**（用户池属性）`email` 时，按照您的 IdP 提供的 SAML 断言中显示的内容，输入 SAML 属性名称。如果 IdP 提供了示例 SAML 断言，您可以使用这些示例断言帮助您查找名称。有些 IdPs 使用简单的名称，例如`email`，而另一些则使用如下所示的名称。

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

1. 选择**创建**。

------
#### [ API/CLI ]

使用以下命令可创建和管理 SAML 身份提供者 (IdP)。

**创建 IdP 并上传元数据文档**
+ AWS CLI: `aws cognito-idp create-identity-provider`

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

  其中 `details.json` 包含：

  ```
  "ProviderDetails": { 
        "MetadataFile": "<SAML metadata XML>",
        "IDPSignout" : "true",
        "RequestSigningAlgorithm" : "rsa-sha256",
        "EncryptedResponses" : "true",
        "IDPInit" : "true"
  }
  ```
**注意**  
如果*<SAML metadata XML>*包含该字符的任何实例`"`，则必须添加`\`为转义字符：`\"`。

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

**为 IdP 上传新的元数据文档**
+ AWS CLI: `aws cognito-idp update-identity-provider`

  带元数据文件的示例：`aws cognito-idp update-identity-provider --user-pool-id us-east-1_EXAMPLE --provider-name=SAML_provider_1 --provider-details file:///details.json --attribute-mapping email=http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress`

  其中 `details.json` 包含：

  ```
  "ProviderDetails": { 
        "MetadataFile": "<SAML metadata XML>",
        "IDPSignout" : "true",
        "RequestSigningAlgorithm" : "rsa-sha256",
        "EncryptedResponses" : "true",
        "IDPInit" : "true"
  }
  ```
**注意**  
如果*<SAML metadata XML>*包含该字符的任何实例`"`，则必须添加`\`为转义字符：`\"`。

  带元数据 URL 的示例：`aws cognito-idp update-identity-provider --user-pool-id us-east-1_EXAMPLE --provider-name=SAML_provider_1 --provider-details MetadataURL=https://myidp.example.com/sso/saml/metadata --attribute-mapping email=http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress`
+ AWS API: [UpdateIdentityProvider](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateIdentityProvider.html)

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

  `aws cognito-idp describe-identity-provider --user-pool-id us-east-1_EXAMPLE --provider-name=SAML_provider_1`
+ AWS API: [DescribeIdentityProvider](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_DescribeIdentityProvider.html)

**列出所有相关信息 IdPs**
+ AWS CLI: `aws cognito-idp list-identity-providers`

  示例：`aws cognito-idp list-identity-providers --user-pool-id us-east-1_EXAMPLE --max-results 3`
+ AWS API: [ListIdentityProviders](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_ListIdentityProviders.html)

**删除 IdP**
+ AWS CLI: `aws cognito-idp delete-identity-provider`

  `aws cognito-idp delete-identity-provider --user-pool-id us-east-1_EXAMPLE --provider-name=SAML_provider_1`
+ AWS API: [DeleteIdentityProvider](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_DeleteIdentityProvider.html)

------

**设置 SAML IdP 以添加用户池作为信赖方**
+ 用户池服务提供商 URN 为：`urn:amazon:cognito:sp:us-east-1_EXAMPLE`。Amazon Cognito 要求受众限制值与 SAML 响应中的这个 URN 相匹配。将您的 IdP 配置为使用以下 POST 绑定端点 IdP-to-SP作为响应消息。

  ```
  https://mydomain.auth.us-east-1.amazoncognito.com/saml2/idpresponse
  ```
+ 您的 SAML IdP 必须在 SAML 断言中为用户池填入 `NameID` 和任何必需属性。`NameID` 用于在用户池中唯一地标识您的 SAML 联合用户。您的 IdP 必须以一致、区分大小写的格式传递每个用户的 SAML 名称 ID。用户名 ID 值发生任何变化都会创建一个新的用户配置文件。

**向您的 SAML 2.0 IDP 提供签名证书**
+ 要从 Amazon Cognito 下载公钥的副本，让您的 IdP 可使用该副本来验证 SAML 注销请求，请选择用户池的**社交和外部提供商**菜单，选择您的 IdP，然后在**查看签名证书**下面，选择**以 .crt 格式下载证书**。

您可以使用 Amazon Cognito 控制台删除在用户池中设置的任何 SAML 提供商。

**删除 SAML 提供者**

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

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

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

1. 选择要删除的 SAML IdPs 旁边的单选按钮。

1. 当系统提示您 **Delete identity provider**（删除身份提供者）时，请输入 SAML 提供商的名称以确认删除，然后选择 **Delete**（删除）。

# SAML 会话在 Amazon Cognito 用户池中启动
<a name="cognito-user-pools-SAML-session-initiation"></a>

Amazon Cognito 支持服务提供商发起（SP 发起）的单点登录（SSO）和 IdP 发起的 SSO。作为一项最佳安全实践，请在用户池中实施 SP 发起的 SSO。[SAML V2.0 技术概述](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0-cd-02.html#5.1.2.SP-Initiated%20SSO:%20%20Redirect/POST%20Bindings|outline)的第 5.1.2 节描述了 SP 启动的 SSO。Amazon Cognito 是您的应用程序的身份提供者 (IdP)。该应用程序是为经过身份验证的用户检索令牌的服务提供程序 (SP)。但是，当您使用第三方 IdP 对用户进行身份验证时，Amazon Cognito 就是 SP。SAML 2.0 用户使用 SP 发起的流程进行身份验证时，他们始终必须先向 Amazon Cognito 发出请求并重定向到 IdP 进行身份验证。

对于某些企业使用案例，对内部应用程序的访问从企业 IdP 托管的控制面板上的书签开始。当用户选择书签时，IdP 会生成一个 SAML 响应并将其发送到 SP 以向应用程序验证用户身份。

您可以在用户池中配置 SAML IdP，以便支持 IdP 发起的 SSO。在支持 IdP 发起的身份验证时，因为 Amazon Cognito 不会通过 SAML 请求发起身份验证，所以 Amazon Cognito 无法验证它是否请求了收到的 SAML 响应。在 SP 发起的 SSO 中，Amazon Cognito 会设置状态参数，用以根据原始请求验证 SAML 响应。通过 SP 发起的登录，您还可以防止跨站点请求伪造（CSRF）攻击。

**Topics**
+ [实施 SP 发起的 SAML 登录](#cognito-user-pools-saml-idp-authentication)
+ [实施 IdP 发起的 SAML 登录](#cognito-user-pools-SAML-session-initiation-idp-initiation)

## 实施 SP 发起的 SAML 登录
<a name="cognito-user-pools-saml-idp-authentication"></a>

最佳做法是实现 service-provider-initiated（由 SP 发起的）用户池登录。Amazon Cognito 会启动用户的会话并将他们重定向到您的 IdP。使用这种方法，您可以更大限度地控制谁提出登录请求。在某些条件下，您也可以允许 IdP 发起的登录。

以下过程显示了用户如何通过 SAML 提供者完成 SP 发起的用户池登录。

![\[Amazon Cognito SP 发起的 SAML 登录的身份验证流程图。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/scenario-authentication-saml-stepbystep.png)


1. 您的用户在登录页面输入他们的电子邮件地址。要确定您的用户是否重定向到其 IdP，您可以在自定义构建的应用程序中收集他们的电子邮件地址，或者在 Web 视图中调用托管登录。

   您可以将托管登录页面配置为显示电子邮件地址列表 IdPs或提示输入电子邮件地址，然后将其与 SAML IdP 的标识符进行匹配。要提示输入电子邮件地址，请编辑您的托管登录品牌风格，然后在**基础**中找到**身份验证行为**，然后在**提供商显示**下，将**显示风格**设置为**域搜索输入**。

1. 您的应用程序调用您的用户池重定向端点，并请求使用与应用程序对应的客户端 ID 以及与用户对应的 IdP ID 进行会话。

1. Amazon Cognito 使用（可选择在 `AuthnRequest` 元素中[签署](cognito-user-pools-SAML-signing-encryption.md#cognito-user-pools-SAML-signing.title)的）SAML 请求将您的用户重定向到 IdP。

1. IdP 以交互方式或通过浏览器 Cookie 中记住的会话对用户进行身份验证。

1. IdP 使用其 POST 有效载荷中[可选的加密](cognito-user-pools-SAML-signing-encryption.md#cognito-user-pools-SAML-signing-encryption.title) SAML 断言将用户重定向到用户池 SAML 响应端点。
**注意**  
Amazon Cognito 会取消在 5 分钟内未收到响应的会话，并将用户重定向到托管登录。当您的用户遇到此结果时，他们会收到一条 `Something went wrong` 错误消息。

1. 在验证 SAML 断言并从响应中的声明[映射用户属性](cognito-user-pools-specifying-attribute-mapping.md#cognito-user-pools-specifying-attribute-mapping.title)后，Amazon Cognito 在用户池中内部创建或更新用户的配置文件。通常，您的用户池会向用户的浏览器会话返回授权码。

1. 您的用户向您的应用程序出示他们的授权码，您的应用程序会将该代码兑换 JSON 网络令牌 (JWTs)。

1. 应用程序接受并处理用户的 ID 令牌作为身份验证，使用其访问令牌生成对资源的授权请求，并存储他们的刷新令牌。

当用户进行身份验证并接收授权码授予时，用户池会返回 ID 令牌、访问令牌和刷新令牌。ID 令牌是基于 OIDC 的身份管理的身份验证对象。访问令牌是一个范围为 [OAuth 2.0](https://oauth.net/2/) 的授权对象。刷新令牌是在用户当前令牌到期时生成新 ID 令牌和访问令牌的对象。您可以在用户池应用程序客户端中配置用户令牌的持续时间。

您还可以选择刷新令牌的持续时间。用户的刷新令牌到期后，他们必须重新登录。如果他们通过 SAML IdP 进行身份验证，则用户的会话持续时间由其令牌的到期时间，而不是他们与 IdP 的会话到期时间来设置。您的应用程序必须存储每位用户的刷新令牌，并在刷新令牌到期时更新他们的会话。托管登录会在浏览器的 Cookie 中维持用户的会话，这个 Cookie 的有效期为 1 小时。

## 实施 IdP 发起的 SAML 登录
<a name="cognito-user-pools-SAML-session-initiation-idp-initiation"></a>

在为 IdP 发起的 SAML 2.0 登录配置身份提供者时，您可以向用户池域中的 `saml2/idpresponse` 端点提供 SAML 断言，而无需在 [对端点授权](authorization-endpoint.md) 启动会话。具有此配置的用户池接受从用户池外部身份提供者由 IdP 发起的 SAML 断言，前提是所请求的应用程序客户端支持这种断言。

![\[Amazon Cognito IdP 发起的 SAML 登录的身份验证流程图。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/scenario-authentication-saml-idpinit.png)


1. 用户请求使用您的应用程序进行 SAML 登录。

1. 您的应用程序调用浏览器或将用户重定向到其 SAML 提供商的登录页面。

1. IdP 以交互方式或通过浏览器 Cookie 中记住的会话对用户进行身份验证。

1. IdP 使用 POST 正文中的 SAML 断言或响应将用户重定向到您的应用程序。

1. 您的应用程序将 SAML 断言添加到您的用户池 `saml2/idpresponse` 端点请求的 POST 正文中。

1. Amazon Cognito 向您的用户发出授权码。

1. 您的用户向您的应用程序出示他们的授权码，您的应用程序会将该代码兑换 JSON 网络令牌 (JWTs)。

1. 应用程序接受并处理用户的 ID 令牌作为身份验证，使用其访问令牌生成对资源的授权请求，并存储他们的刷新令牌。

以下步骤描述了配置 IdP 发起的 SAML 2.0 提供者并使用它来登录的整个过程。

1. 创建或指定用户池和应用程序客户端。

1. 在您的用户池中创建 SAML 2.0 IdP。

1. 将您的 IdP 配置为支持 IdP 启动。IdP 发起的 SAML 引入了一些安全性考量，而其他 SSO 提供者没有涉及这些安全性考量。因此，您无法将非 SAML IdPs（包括用户池本身）添加到任何使用 SAML 提供商并通过 IDP 启动登录的应用程序客户端。

1. 将 IdP 发起的 SAML 提供者与用户池中的应用程序客户端关联。

1. 将您的用户引导至 SAML IdP 的登录页面并检索 SAML 断言。

1. 使用 SAML 断言将用户引导至用户池 `saml2/idpresponse` 端点。

1. 接收 JSON 网络令牌 (JWTs)。

要在用户池中接受未经请求的 SAML 断言，必须考虑其对应用程序安全性的影响。当您接受 IdP 发起的请求时，可能会出现请求欺骗和 CSRF 尝试情况。虽然用户池无法验证 IdP 发起的登录会话，但 Amazon Cognito 会验证请求参数和 SAML 断言。

此外，SAML 声明不得包含 `InResponseTo` 声明，并且必须在前 6 分钟内发出。

您必须使用 IdP 发起的 SAML 向您的 `/saml2/idpresponse` 提交请求。对于 SP 发起的请求和托管登录授权请求，您必须提供参数，将您请求的应用程序客户端、范围、重定向 URI 和其他详细信息标识为 `HTTP GET` 请求中的查询字符串参数。但是，对于 IdP 发起的 SAML 断言，必须将请求的详细信息的格式设置为 `HTTP POST` 请求正文中的 `RelayState` 参数。请求正文还必须包含您的 SAML 断言，作为 `SAMLResponse` 参数。

以下是 IdP 发起的 SAML 提供商的示例请求和响应。

```
POST /saml2/idpresponse HTTP/1.1
User-Agent: USER_AGENT
Accept: */*
Host: example.auth.us-east-1.amazoncognito.com
Content-Type: application/x-www-form-urlencoded

SAMLResponse=[Base64-encoded SAML assertion]&RelayState=identity_provider%3DMySAMLIdP%26client_id%3D1example23456789%26redirect_uri%3Dhttps%3A%2F%2Fwww.example.com%26response_type%3Dcode%26scope%3Demail%2Bopenid%2Bphone

HTTP/1.1 302 Found
Date: Wed, 06 Dec 2023 00:15:29 GMT
Content-Length: 0
x-amz-cognito-request-id: 8aba6eb5-fb54-4bc6-9368-c3878434f0fb
Location: https://www.example.com?code=[Authorization code]
```

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

**为 IdP 发起的 SAML 配置 IdP**

1. 创建[用户池](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-as-user-directory.html)、[应用程序客户端](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-configuring-app-integration.html)和 SAML 身份提供者。

1. 取消所有社交和 OIDC 身份提供者与应用程序客户端的关联（如果已关联）。

1. 导航到用户池的**社交和外部提供商**菜单。

1. 编辑或添加 SAML 提供商。

1. 在 **IdP 发起的 SAML 登录**下，选择**接受 SP 发起和 IdP 发起的 SAML 断言**。

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

------
#### [ API/CLI ]

**为 IdP 发起的 SAML 配置 IdP**

使用[CreateIdentityProvider](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateIdentityProvider.html)或 [UpdateIdentityProvider](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateIdentityProvider.html)API 请求中的`IDPInit`参数配置 IDP 启动的 SAML。以下是支持 IdP 发起的 SAML 的 IdP 的示例 `ProviderDetails`。

```
"ProviderDetails": { 
      "MetadataURL" : "https://myidp.example.com/saml/metadata",
      "IDPSignout" : "true",
      "RequestSigningAlgorithm" : "rsa-sha256",
      "EncryptedResponses" : "true",
      "IDPInit" : "true"
}
```

------

# 通过单点注销来注销 SAML 用户
<a name="cognito-user-pools-saml-idp-sign-out"></a>

Amazon Cognito 支持 SAML 2.0 [单点注销](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0-cd-02.html#5.3.Single%20Logout%20Profile|outline) (SLO)。 借助 SLO，当用户从您的用户池中注销时，您的应用程序可以从其 SAML 身份提供商 (IdPs) 中注销他们。这样，当用户想要再次登录应用程序时，他们必须使用其 SAML IdP 进行身份验证。如果不这样做，他们可能会因为在浏览器中有 IdP 或用户池 Cookie，所以无需提供凭证即可进入您的应用程序。

当您将 SAML IdP 配置为支持**注销流程**时，Amazon Cognito 会通过已签名的 SAML 注销请求将您的用户重定向到您的 IdP。Amazon Cognito 根据您的 IdP 元数据中的 `SingleLogoutService` URL 确定重定向位置。Amazon Cognito 使用您的用户池签名证书签署注销请求。

![\[Amazon Cognito SAML 注销的身份验证流程图。用户请求注销，然后 Amazon Cognito 通过 SAML 注销请求将他们重定向到其提供者。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/scenario-authentication-saml-sign-out.png)


当您将具有 SAML 会话的用户定向到您的用户池 `/logout` 端点时，Amazon Cognito 会将您的 SAML 用户通过以下请求重定向到 IdP 元数据中指定的 SLO 端点。

```
https://[SingleLogoutService endpoint]?
SAMLRequest=[encoded SAML request]&
RelayState=[RelayState]&
SigAlg=http://www.w3.org/2001/04/xmldsig-more#rsa-sha256&
Signature=[User pool RSA signature]
```

然后，您的用户使用来自其 IdP 的 `LogoutResponse` 返回到您的 `saml2/logout` 端点。您的 IdP 必须在 `HTTP POST` 请求中发送 `LogoutResponse`。然后，Amazon Cognito 会根据他们最初的注销请求将他们重定向到重定向目的地。

您的 SAML 提供者可能会发送包含多个 `AuthnStatement` 的 `LogoutResponse`。此类响应中第一个 `AuthnStatement` 中的 `sessionIndex` 必须与最初对用户进行身份验证的 SAML 响应中的 `sessionIndex` 匹配。如果 `sessionIndex` 在任何其他 `AuthnStatement` 中，则 Amazon Cognito 将无法识别会话，且您的用户不会注销。

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

**配置 SAML 注销**

1. 创建[用户池](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-as-user-directory.html)、[应用程序客户端](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-configuring-app-integration.html)和 SAML IdP。

1. 创建或编辑 SAML 身份提供者时，在**身份提供者信息**下，选中名称为**添加注销流程**的复选框。

1. 从用户池的**社交和外部提供商**菜单中，选择您的 IdP 并找到**签名证书**。

1. 选择**以 .crt 格式下载证书**。

1. 将您的 SAML 提供者配置为支持 SAML 单点注销和请求签名，然后上传用户池签名证书。您的 IdP 必须重定向到用户池域中的 `/saml2/logout`。

------
#### [ API/CLI ]

**配置 SAML 注销**

使用[CreateIdentityProvider](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateIdentityProvider.html)或 [UpdateIdentityProvider](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateIdentityProvider.html)API 请求的`IDPSignout`参数配置单次注销。以下是支持 SAML 单点注销的 IdP 的示例 `ProviderDetails`。

```
"ProviderDetails": { 
      "MetadataURL" : "https://myidp.example.com/saml/metadata",
      "IDPSignout" : "true",,
      "RequestSigningAlgorithm" : "rsa-sha256",
      "EncryptedResponses" : "true",
      "IDPInit" : "true"
}
```

------

# SAML 签名和加密
<a name="cognito-user-pools-SAML-signing-encryption"></a>

SAML 2.0 登录围绕着应用程序的用户作为其身份验证流程中的请求和响应的持有者来进行。您可能需要确保用户不会在传输过程中读取或修改这些 SAML 文档。为此，请将 SAML 签名和加密添加到用户池中的 SAML 身份提供商 (IdPs)。借助 SAML 签名，您的用户池可向 SAML 登录和注销请求添加签名。使用您的用户池公钥，IdP 可以验证它接收的是未经修改的 SAML 请求。然后，当您的 IdP 响应并将 SAML 断言传递给用户的浏览器会话时，IdP 可以加密该响应，这样用户就无法查看自己的属性和权限。

使用 SAML 签名和加密，用户池 SAML 操作期间的所有加密操作都必须使用 user-pool-provided Amazon Cognito 生成的密钥生成签名和密文。目前，无法将用户池配置为使用外部密钥签署请求或接受加密断言。

**注意**  
用户池证书有效期为 10 年。Amazon Cognito 每年都会为用户池生成一次新的签名和加密证书。请求签名证书时，Amazon Cognito 会返回最新的证书，并使用最新的签名证书来签署请求。IdP 可以使用任何未过期的用户池加密证书来加密 SAML 断言。之前的证书在整个有效期内继续有效，并且不同证书之间的公钥不会发生变化。作为一项最佳实践，请每年更新提供者配置中的证书。

**Topics**
+ [接受来自 IdP 的加密 SAML 响应](#cognito-user-pools-SAML-encryption)
+ [签署 SAML 请求](#cognito-user-pools-SAML-signing)

## 接受来自 IdP 的加密 SAML 响应
<a name="cognito-user-pools-SAML-encryption"></a>

当用户登录和注销时，Amazon Cognito 和您的 IdP 可以在 SAML 响应中保持机密性。Amazon Cognito 会向您在用户池中配置的每个外部 SAML 提供者分配一个公有-私有 RSA 密钥对和一个证书。为用户池 SAML 提供者启用响应加密时，必须将证书上传到支持加密 SAML 响应的 IdP。在您的 IdP 开始使用提供的密钥加密所有 SAML 断言之前，您的用户池与 SAML IdP 的连接无法正常工作。

下文概述了加密 SAML 登录的流程。

1. 您的用户开始登录并选择他们的 SAML IdP。

1. 您的用户池 [对端点授权](authorization-endpoint.md) 通过 SAML 登录请求将您的用户重定向到他们的 SAML IdP。您的用户池可以选择在此请求中附上签名，从而让 IdP 可以进行完整性验证。当您想要签署 SAML 请求时，必须将您的 IdP 配置为接受您的用户池使用签名证书中的公钥签署的请求。

1. SAML IdP 让您的用户登录并生成 SAML 响应。IdP 使用公钥对响应进行加密，并将用户重定向到用户池 `/saml2/idpresponse` 端点。IdP 必须按照 SAML 2.0 规范的定义对响应进行加密。有关更多信息，请参阅 [OASIS 安全断言标记语言（SAML）V2.0 的断言和协议](https://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf)中的 `Element <EncryptedAssertion>`。

1. 用户池使用私钥解密 SAML 响应中的加密文字并让您的用户登录。

**重要**  
当您为用户池中的 SAML IdP 启用响应加密时，您的 IdP 必须使用该提供者特有的公钥对所有响应进行加密。Amazon Cognito 不接受来自您配置为支持加密的 SAML 外部 IdP 的未加密 SAML 响应。

用户池中的任何外部 SAML IdP 都可以支持响应加密，并且每个 IdP 都会收到自己的密钥对。

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

**配置 SAML 响应加密**

1. 创建[用户池](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-as-user-directory.html)、[应用程序客户端](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-configuring-app-integration.html)和 SAML IdP。

1. 创建或编辑 SAML 身份提供者时，在**对请求进行签名并加密响应**下，选中名称为**需要此提供商的加密 SAML 断言**的复选框。

1. 从用户池的**社交和外部提供商**菜单中，选择您的 SAML IdP，然后选择**查看加密证书**。

1. 选择**以 .crt 格式下载证书**，然后将下载的文件提供给您的 SAML IdP。将您的 SAML IdP 配置为使用证书中的密钥加密 SAML 响应。

------
#### [ API/CLI ]

**配置 SAML 响应加密**

使用[CreateIdentityProvider](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateIdentityProvider.html)或 [UpdateIdentityProvider](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateIdentityProvider.html)API 请求的`EncryptedResponses`参数配置响应加密。以下是支持请求签名的 IdP 的示例 `ProviderDetails`。

```
"ProviderDetails": { 
      "MetadataURL" : "https://myidp.example.com/saml/metadata",
      "IDPSignout" : "true",
      "RequestSigningAlgorithm" : "rsa-sha256",
      "EncryptedResponses" : "true",
      "IDPInit" : "true"
}
```

要从您的用户池中获取加密证书，请发出 [DescribeIdentityProvider](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_DescribeIdentityProvider.html)API 请求并在响应参数`ActiveEncryptionCertificate`中检索的值`ProviderDetails`。保存此证书，并将其作为加密证书提供给您的 IdP，用于接收来自用户池的登录请求。

------

## 签署 SAML 请求
<a name="cognito-user-pools-SAML-signing"></a>

能够向您的 IdP 证明 SAML 2.0 请求的完整性是 Amazon Cognito SP 发起的 SAML 登录的一项安全优势。每个拥有域的用户池都会收到一个用户池 X.509 签名证书。使用此证书中的公钥，用户池将加密签名应用于在用户选择 SAML IdP 时用户池生成的*注销请求*。您可以选择将应用程序客户端配置为签署 SAML *登录请求*。当您签署 SAML 请求时，您的 IdP 会核实请求的 XML 元数据中的签名是否与您提供的用户池证书中的公钥相匹配。

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

**配置 SAML 请求签名**

1. 创建[用户池](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-as-user-directory.html)、[应用程序客户端](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-configuring-app-integration.html)和 SAML IdP。

1. 创建或编辑 SAML 身份提供者时，在**对请求进行签名并加密响应**下，选中名称为**对此提供商的 SAML 请求进行签名**的复选框。

1. 从用户池的**社交和外部提供商**菜单中，选择**查看签名证书**。

1. 选择**以 .crt 格式下载证书**，然后将下载的文件提供给您的 SAML IdP。配置 SAML IdP 以验证传入 SAML 请求的签名。

------
#### [ API/CLI ]

**配置 SAML 请求签名**

使用[CreateIdentityProvider](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateIdentityProvider.html)或 [UpdateIdentityProvider](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateIdentityProvider.html)API 请求的`RequestSigningAlgorithm`参数配置请求签名。以下是支持请求签名的 IdP 的示例 `ProviderDetails`。

```
"ProviderDetails": { 
      "MetadataURL" : "https://myidp.example.com/saml/metadata",
      "IDPSignout" : "true",
      "RequestSigningAlgorithm" : "rsa-sha256",
      "EncryptedResponses" : "true",
      "IDPInit" : "true"
}
```

------

# SAML 身份提供者名称和标识符
<a name="cognito-user-pools-managing-saml-idp-naming"></a>

当您命名您的 SAML 身份提供商 (IdPs) 并分配 IdP 标识符时，您可以自动将 SP 发起的登录和注销请求流向该提供商。有关提供商名称的字符串约束的信息，请参阅的`ProviderName`属性[CreateIdentityProvider](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateIdentityProvider.html#CognitoUserPools-CreateIdentityProvider-request-ProviderName)。

![\[使用 IdP 标识符和托管登录的 Amazon Cognito SP 发起的 SAML 登录的身份验证流程图。用户向托管登录提供电子邮件地址，Amazon Cognito 会自动将他们重定向到其提供者。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/scenario-authentication-saml-identifier.png)


您还可以为 SAML 提供商选择最多 50 个标识符。标识符是用户池中 IdP 的友好名称，并且在用户池中必须是唯一的。如果您的 SAML 标识符与用户的电子邮件域匹配，托管登录会请求每个用户的电子邮件地址，评估其电子邮件地址中的域，然后将他们重定向到与其域对应的 IdP。由于同一个组织可以拥有多个域，因此单个 IdP 可以有多个标识符。

无论您是使用还是不使用电子邮件域标识符，您都可以在多租户应用程序中使用标识符将用户重定向到正确的 IdP。当您想完全绕过托管登录时，可以自定义向用户提供的链接，这样他们就可以通过 [对端点授权](authorization-endpoint.md) 直接重定向到他们的 IdP。要使用标识符使您的用户登录并重定向到他们的 IdP，请在其初始授权请求的请求参数中包括 `idp_identifier=myidp.example.com` 格式的标识符。

将用户传递到 IdP 的另一种方法是使用以下 URL 格式的 IdP 名称填充参数 `identity_provider`。

```
https://mydomain.auth.us-east-1.amazoncognito.com/oauth2/authorize?
response_type=code&
identity_provider=MySAMLIdP&
client_id=1example23456789&
redirect_uri=https://www.example.com
```

用户使用您的 SAML IdP 登录后，您的 IdP 会将他们重定向到您的 `/saml2/idpresponse` 端点，并在 `HTTP POST` 正文中包括一个 SAML 响应。Amazon Cognito 会处理 SAML 断言，如果响应中的声明符合预期，则会重定向到您的应用程序客户端回调 URL。在用户以这种方式完成身份验证后，他们只与您的 IdP 和您的应用程序的网页进行交互。

使用域格式的 IdP 标识符，托管登录会在登录时请求电子邮件地址，然后，当电子邮件域与 IdP 标识符匹配时，将用户重定向到其 IdP 的登录页面。例如，您构建一个需要两家不同公司的员工登录的应用程序。第一家公司 AnyCompany A 拥有`exampleA.com`和`exampleA.co.uk`。第二家公司 AnyCompany B 拥有`exampleB.com`。在本示例中，您设置了两个 IdPs，每家公司一个，如下所示：
+ 对于 IdP A，您定义标识符 `exampleA.com` 和 `exampleA.co.uk`。
+ 对于 IdP B，您定义标识符 `exampleB.com`。

在您的应用程序中，调用应用程序客户端的托管登录，提示每位用户输入其电子邮件地址。Amazon Cognito 根据电子邮件地址得出域，将该域与具有域标识符的 IdP 关联起来，然后通过向包含 `idp_identifier` 请求参数的 [对端点授权](authorization-endpoint.md) 发出请求，将您的用户重定向到正确的 IdP。例如，如果用户输入 `bob@exampleA.co.uk`，则他们与之交互的下一个页面是位于 `https://auth.exampleA.co.uk/sso/saml` 的 IdP 登录页面。

您也可以独立实施相同的逻辑。在您的应用程序中，您可以构建一个自定义表单，用于收集用户输入并根据自己的逻辑将其与正确的 IdP 关联起来。您可为每个应用程序租户生成自定义门户，其中每个租户都通过请求参数中的租户标识符链接到授权端点。

要在托管登录中收集电子邮件地址并解析域，请为您分配给应用程序客户端的每个 SAML IdP 至少分配一个标识符。默认情况下，托管登录屏幕会针对您分配给应用程序客户端 IdPs的每个登录显示一个按钮。但如果您已成功分配标识符，则经典托管 UI 登录页面将如下图所示。

![\[Amazon Cognito 托管登录的登录页面，显示本地用户登录和要求联合用户输入电子邮件地址的提示。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/cup-saml-identifiers.png)


**注意**  
在经典托管用户界面中，当您为应用程序客户端分配标识符时，应用程序客户端的登录页面会自动提示您输入电子邮件地址。 IdPs在托管登录体验中，您必须在品牌编辑器中启用此行为。在**身份验证行为**设置类别中，在**提供商显示**标题下选择**域搜索输入**。

在托管登录中解析域时，要求使用域作为 IdP 标识符。如果您为应用程序客户端的每个 SAML IdPs 分配了任何类型的标识符，则该应用程序的托管登录将不再显示 IDP 选择按钮。当您打算使用电子邮件解析或自定义逻辑生成重定向时，请为 SAML 添加 IdP 标识符。如果您想生成静默重定向，同时希望托管登录页面显示列表，请不要分配标识符 IdPs，也不要在授权`identity_provider`请求中使用请求参数。
+ 如果您仅将一个 SAML IdP 分配给您的应用程序客户端，则托管登录的登录页面会显示一个用于使用该 IdP 登录的按钮。
+ 如果您向为应用程序客户端激活的每个 SAML IdP 分配一个标识符，则在托管登录的登录页面中会出现要求用户输入电子邮件地址的提示。
+ 如果您有多个 IdPs ，但没有为所有用户分配标识符，则托管登录页面会显示一个按钮，用于使用每个分配的 IdP 进行登录。
+ 如果您为自己分配了标识符， IdPs 并且希望托管登录页面显示精选的 IdP 按钮，请向您的应用程序客户端添加一个没有标识符的新 IdP，或者创建一个新的应用程序客户端。您也可以删除现有 IdP，然后在没有标识符的情况下重新添加它。如果您创建新的 IdP，则您的 SAML 用户将创建新的用户配置文件。活跃用户的重复计数可能会在您更改 IdP 配置的当月对账单产生影响。

有关 IdP 设置的更多信息，请参阅[为用户池配置身份提供者](cognito-user-pools-identity-provider.md)。