

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

# 为企业应用程序选择 Amazon Cognito 身份验证流程
<a name="choose-an-amazon-cognito-authentication-flow-for-enterprise-applications"></a>

*Michael Daehnert 和 Fabian Jahnke，Amazon Web Services*

## Summary
<a name="choose-an-amazon-cognito-authentication-flow-for-enterprise-applications-summary"></a>

[Amazon Cognito](https://docs.aws.amazon.com/cognito/latest/developerguide/what-is-amazon-cognito.html) 为您的 Web 和移动应用程序提供身份验证、授权和用户管理。它为联合身份的身份验证提供了实用功能。要使其启动并运行，技术架构师需要决定如何使用这些功能。

Amazon Cognito 支持多种身份验证请求流程。这些流程定义了您的用户如何进行身份验证。决定使用哪种身份验证流程取决于您的应用程序的特定要求，并且可能会变得复杂。此模式可帮助您确定哪种身份验证流程最适合您的企业应用程序。假设您已掌握了有关 Amazon Cognito、OpenID Connect（OIDC）和联合身份验证的基本知识，而这些知识可指导您详细了解不同的联合身份验证流程。

该解决方案适用于技术决策者，可以帮助您了解不同的身份验证流程，并将其与您的应用程序要求进行匹配。技术主管应收集所需见解，以启动 Amazon Cognito 集成。由于企业组织主要关注 SAML 联合身份验证，因此此模式包括对具有 SAML 联合身份验证的 [Amazon Cognito 用户池](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html)的描述。

## 先决条件和限制
<a name="choose-an-amazon-cognito-authentication-flow-for-enterprise-applications-prereqs"></a>

**先决条件**
+ 一个活跃的 AWS 账户
+ AWS Identity and Acccess Management（IAM）角色和权限，具有 Amazon Cognito 完全访问权限
+ （可选）访问身份提供者（IdP），例如 Microsoft Entra ID、Active Directory Federation Service（AD FS）或 Okta
+ 具有高水平的应用程序专业知识
+ Amazon Cognito、OpenID Connect（OIDC）和联合身份验证的基础知识

**限制**
+ 此模式侧重于 Amazon Cognito 用户池和身份提供者。有关 Amazon Cognito Cognito 身份池的信息，请参阅[其他信息](#choose-an-amazon-cognito-authentication-flow-for-enterprise-applications-additional)部分。

## 架构
<a name="choose-an-amazon-cognito-authentication-flow-for-enterprise-applications-architecture"></a>

使用下表来帮助您选择身份验证流程。本部分提供了有关每个流程的更多信息。


| 
| 
| 你需要 machine-to-machine身份验证吗？ | 您的应用程序是否是基于 Web 的应用程序，且其前端是否在服务器上进行渲染？ | 应用程序是单页应用程序（SPA）还是移动前端应用程序？ | 您的应用程序是否需要刷新令牌才能使用“让我保持登录状态”功能？ | 前端是否提供基于浏览器的重定向机制？ | 建议使用 Amazon Cognito 流程 | 
| --- |--- |--- |--- |--- |--- |
| 是 | 否 | 否 | 否 | 否 | 客户端凭证流 | 
| 否 | 是 | 否 | 是 | 是 | 授权码流 | 
| 否 | 否 | 是 | 是 | 是 | 具有代码交换的证明密钥（PKCE）的授权代码流 | 
| 否 | 否 | 否 | 否 | 否 | 资源所有者密码流\$1 | 

\$1 只有在绝对必要时才应使用资源所有者密码流。有关更多信息，请参阅此模式中的*资资源所有者密码流*部分。

**客户端凭证流**

客户端凭证流是 Amazon Cognito 流程中最短的流程。如果系统或服务之间无需任何用户交互即可相互通信，则应使用此方法。发出请求的系统使用客户端 ID 和客户端密钥来检索访问令牌。由于这两个系统都无需用户交互即可运行，因此无需额外的同意步骤。

![\[Amazon Cognito 的客户端凭证流\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/7b5e567c-66a4-4386-a1f6-616ed77a6211/images/1138745d-69fa-4ecc-a9ec-c0b2a68ce7d2.png)


下图说明了以下内容：

1. 应用程序 1 向 Amazon Cognito 端点发送包含客户端 ID 和客户端密钥的身份验证请求，然后它会检索访问令牌。

1. 应用程序 1 在随后对应用程序 2 的每次调用中都会使用此访问令牌。

1. 应用程序 2 使用 Amazon Cognito 验证访问令牌。

应使用此流程：
+ 对于应用程序之间的通讯，且无需用户交互

不应使用此流程：
+ 对于任何可能进行用户交互的通信

**授权码流**

授权码流适用于基于 Web 的经典身份验证。在此流程中，后端可处理所有的令牌交换和存储。基于浏览器的客户端无法看到实际令牌。此解决方案用于在 .NET Core、Jakarta Faces 或 Jakarta Server Pages（JSP）等框架中编写的应用程序。

授权码流是一个基于重定向的流程。客户端必须能够与 Web 浏览器或类似的客户端进行交互。客户端被重定向到身份验证服务器并使用该服务器进行身份验证。如果客户端成功通过身份验证，则会将其重定向回服务器。

![\[Amazon Cognito 的授权代码流\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/7b5e567c-66a4-4386-a1f6-616ed77a6211/images/1008296c-d5b8-449d-99d4-f0b2b7cf5d80.png)


下图说明了以下内容：

1. 客户端向 Web 服务器发送请求。

1. Web 服务器使用 HTTP 302 状态码将客户端重定向到 Amazon Cognito。客户端会自动跟随此重定向到配置的 IdP 登录。

1. IdP 在 IdP 端检查现有浏览器会话。如果不存在，则用户会收到一条通过提供用户名和密码进行身份验证的提示。IdP 使用 SAML 令牌向 Amazon Cognito 进行回应。

1. Amazon Cognito 使用 JSON Web 令牌（JWT），特别是代码令牌返回成功。Web 服务器调用 /oauth2/token，以将代码令牌交换为访问令牌。Web 服务器将客户端 ID 和客户端密钥发送到 Amazon Cognito 进行验证。

1. 访问令牌可用于对其他应用程序的每次后续调用。

1. 其他应用程序使用 Amazon Cognito 验证访问令牌。

应使用此流程：
+ 如果用户能够与 Web 浏览器或客户端进行交互。该应用程序代码在服务器上运行和渲染，以确保浏览器不会泄露任何秘密。

不应使用此流程：
+ 适用于单页应用程序 (SPAs) 或移动应用程序，因为它们是在客户端上呈现的，不应使用客户端密钥。

**使用 PKCE 的授权码流**

具有代码交换的证明密钥（PKCE）的授权代码流应用于单页应用程序和移动应用程序。由于采用了 PKCE，它是隐式流的后续版本，并且更加安全。PKCE 是 OAuth 2.0 授权码授予公共客户端的扩展。PKCE 可防止兑换拦截的授权代码。

![\[Amazon Cognito 的具有 PKCE 的授权代码流\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/7b5e567c-66a4-4386-a1f6-616ed77a6211/images/1609da4f-decd-4d43-afe0-31237238df6d.png)


下图说明了以下内容：

1. 应用程序创建代码验证器和代码质询。这些是定义明确的唯一值，可发送到 Amazon Cognito，以供将来参考。

1. 该应用程序调用 Amazon Cognito 的 /oauth2/authorization 端点。它会自动将用户重定向到配置的 IdP 登录名。

1. IdP 会检查是否存在现有会话。如果不存在，则用户会收到一条通过提供用户名和密码进行身份验证的提示。IdP 使用 SAML 令牌向 Amazon Cognito 进行回应。

1. 在 Amazon Cognito 使用代码令牌返回成功后，Web 服务器会调用 /oauth2/token，将代码令牌交换为访问令牌。

1. 访问令牌可用于对其他应用程序的每次后续调用。

1. 其他应用程序使用 Amazon Cognito 验证访问令牌。

应使用此流程：
+ 适用于 SPAs 我们的移动应用程序

不应使用此流程：
+ 如果应用程序后端处理身份验证

**资源所有者密码流**

资源所有者密码流适用于没有重定向功能的应用程序。它是通过在您自己的应用程序中创建登录表单来构建的。在 Amazon Cognito 上，登录是通过 CLI 或 SDK 调用进行检查的，而不是依赖重定向流程。由于联合身份验证需要基于浏览器的重定向，因此无法在此身份验证流程中进行联合身份验证。

![\[Amazon Cognito 的资源所有者密码流\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/7b5e567c-66a4-4386-a1f6-616ed77a6211/images/d74bc596-08a3-40f4-a6a7-07f6610fe6b1.png)


下图说明了以下内容：

1. 用户在应用程序提供的登录表单上输入其凭证。

1. AWS 命令行接口 (AWS CLI) Line Cognito 打电话给 Ama [admin-initiated-auth](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/cognito-idp/admin-initiate-auth.html)zon Cognito。
**注意**  
或者，您可以使用 AWS SDKs 代替 AWS CLI。

1. Amazon Cognito 会返回访问令牌。

1. 访问令牌可用于对其他应用程序的每次后续调用。

1. 其他应用程序使用 Amazon Cognito 验证访问令牌。

应使用此流程：
+ 将使用直接身份验证逻辑（例如基本访问身份验证或摘要访问身份验证）的现有客户端迁移到 OAuth 通过将存储的凭据转换为访问令牌来迁移时

不应使用此流程：
+ 如果你想使用联合身份
+ 如果您的应用程序支持重定向

## 工具
<a name="choose-an-amazon-cognito-authentication-flow-for-enterprise-applications-tools"></a>

**AWS 服务**
+ [Amazon Cognito](https://docs.aws.amazon.com/cognito/latest/developerguide/what-is-amazon-cognito.html) 为您的 Web 和移动应用程序提供身份验证、授权和用户管理。

**其他工具**
+ [JSON Web 令牌（JWT）调试程序](https://jwt.io/)是一个基于 Web 的 JWT 验证工具。

## 操作说明
<a name="choose-an-amazon-cognito-authentication-flow-for-enterprise-applications-epics"></a>

### 评测应用程序
<a name="assess-your-application"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 定义身份验证要求。 | 根据您的特定身份验证要求，评测您的应用程序。 | 应用程序开发人员、应用程序架构师 | 
| 使要求与身份验证流程保持一致。 | 在[架构](#choose-an-amazon-cognito-authentication-flow-for-enterprise-applications-architecture)部分中，使用决策表和每个流程的说明来选择您的 Amazon Cognito 身份验证流程。 | 应用程序开发人员、常规 AWS，应用程序架构师 | 

### 设置 Amazon Cognito 用户池
<a name="set-up-the-amazon-cognito-user-pool"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 创建用户池。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/choose-an-amazon-cognito-authentication-flow-for-enterprise-applications.html) | 常规 AWS | 
| （可选）配置身份提供者。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/choose-an-amazon-cognito-authentication-flow-for-enterprise-applications.html) | 常规 AWS，联合身份验证管理员 | 
| 创建应用程序客户端。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/choose-an-amazon-cognito-authentication-flow-for-enterprise-applications.html) | 常规 AWS | 

### 将应用程序集成到 Amazon Cognito 中
<a name="integrate-the-application-with-amazon-cognito"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 交换 Amazon Cognito 集成详细信息。 | 根据您的身份验证流程，与应用程序共享 Amazon Cognito 信息，例如用户池 ID 和应用程序客户端 ID。 | 应用程序开发人员，常规 AWS | 
| 实施 Amazon Cognito 身份验证。 | 这取决于您选择的身份验证流程、您的编程语言以及您使用的框架。有关一些入门链接，请参阅[相关资源](#choose-an-amazon-cognito-authentication-flow-for-enterprise-applications-resources)部分。 | 应用程序开发人员 | 

## 相关资源
<a name="choose-an-amazon-cognito-authentication-flow-for-enterprise-applications-resources"></a>

**AWS 文档**
+ [用户池身份验证流程](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html)
+ [验证 JSON 网络令牌](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html)
+ [使用 Amazon Cognito 身份池从 ASP.NET 核心应用程序访问 AWS 服务](https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/access-aws-services-from-an-asp-net-core-app-using-amazon-cognito-identity-pools.html?did=pg_card&trk=pg_card)
+ 框架和 SDKs：
  + [Amazon Amplify 身份验证](https://docs.amplify.aws/lib/auth/getting-started/q/platform/js)
  + [Amazon Cognito 身份提供者示例](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/java_cognito-identity-provider_code_examples.html)（适用于 Java 的 AWS SDK 2.x 文档）
  + [使用 Amazon Cognito 对用户进行身份验证](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/cognito-apis-intro.html)（适用于 .NET 的 AWS SDK 文档）

**AWS 博客文章**
+ [使用 Cookie 授权 @Edge：保护您的亚马逊 CloudFront 内容不被未经身份验证的用户下载](https://aws.amazon.com/blogs/networking-and-content-delivery/authorizationedge-using-cookies-protect-your-amazon-cloudfront-content-from-being-downloaded-by-unauthenticated-users/)
+ [使用 Amazon Cognito 用户池为您的 Web 应用程序构建 AD FS 联合身份验证](https://aws.amazon.com/blogs/mobile/building-adfs-federation-for-your-web-app-using-amazon-cognito-user-pools/)

**实施合作伙伴**
+ [提供身份验证解决方案的 AWS 合作伙伴](https://partners.amazonaws.com/search/partners?keyword=authentication)

## 附加信息
<a name="choose-an-amazon-cognito-authentication-flow-for-enterprise-applications-additional"></a>

**常见问题解答**

*为什么放弃使用隐式流程？*

自 [OAuth 2.1 框架](https://oauth.net/2.1/)发布以来，出于安全考虑，隐式流程被标记为已弃用。作为替代方案，请使用[架构](#choose-an-amazon-cognito-authentication-flow-for-enterprise-applications-architecture)部分中描述的具有 PKCE 的授权码流。

*如果 Amazon Cognito 没有提供我需要的某些功能该怎么办？*

AWS 合作伙伴为身份验证和授权解决方案提供不同的集成。有关更多信息，请参阅 [AWS 身份验证解决方案合作伙伴](https://partners.amazonaws.com/search/partners?keyword=authentication)。

*那么 Amazon Cognito 身份池流程呢？*

Amazon Cognito 用户池和联合身份可用于身份验证。Amazon Cognito 身份池用于通过请求临时 AWS 凭证来授权 AWS 资源的访问权限。此模式中未讨论身份池的 ID 令牌和访问令牌交换。有关更多信息，请参阅 [Amazon Cognito 用户池和身份池之间有何区别](https://aws.amazon.com/premiumsupport/knowledge-center/cognito-user-pools-identity-pools/)和 [Amazon Cognito 常见场景](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-scenarios.html)。

**后续步骤**

此模式概述了 Amazon Cognito 身份验证流程。下一步，需要选择应用程序编程语言的详细实施。提供多种语言 SDKs 和框架，您可以将其与 Amazon Cognito 配合使用。有关实用参考资料，请参阅[相关资源](#choose-an-amazon-cognito-authentication-flow-for-enterprise-applications-resources)部分。