

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

# 将 Amazon Cognito 身份验证和授权与 Web 和移动应用程序集成
<a name="cognito-integrate-apps"></a>

Amazon Cognito 的实现是在应用程序中混合使用 AWS 管理控制台 我们的 AWS 软件开发工具包管理工具和软件开发工具包库。Amazon Cognito 控制台是用于设置和管理 Amazon Cognito 用户池和身份池的直观界面。

使用 Amazon Cognito 用户池可以创建的最省力的集成是[托管登录](cognito-terms.md#terms-managedlogin)。托管登录是一款 ready-to-use基于 Web 的登录应用程序，用于快速测试和部署 Amazon Cognito 用户池。使用托管登录进行用户池身份验证需要使用引导用户访问托管登录页面的 OpenID Connect（OIDC）库。在这一系列用户交互式和重定向 Web 端点中，Amazon Cognito 负责处理身份验证流程，包括第三方登录、多重身份验证（MFA）和选择身份验证流程。您的应用程序只需处理 Amazon Cognito 在响应中返回的身份验证结果即可。

您还可以向应用程序添加 S AWS DK、自定义构建身份验证接口，并调用 API 操作对用户进行身份验证和授权。 [AWS Amplify](https://docs.amplify.aws/) AWS 服务 用于构建全栈应用程序，后端使用 Amazon Cognito 身份验证。

例如，应用程序可能会调用托管登录进行用户登录，然后从应用程序代码中调用令牌端点，以便通过交换用户的授权码来获取令牌。然后，应用程序必须解释和存储用户的令牌，并在适当的上下文中出示它们以进行身份验证和授权。Amplify 为这些流程添加了带有内置功能的引导式集成工具。

您也可以完全在代码中构建您的 Amazon Cognito 资源。身份池的托管身份验证选项与用户池不同，要访问应用程序中的 AWS 证书，请在导入的 SDK 模块中实现身份池操作。要开始使用自己的自定义应用程序代码，请访问 Amazon [Cognito 代码](https://docs.aws.amazon.com/cognito/latest/developerguide/service_code_examples.html)示例。[AWS SDKs](https://aws.amazon.com/developer/tools/)要将 Amazon Cognito 作为 OpenID Connect 身份提供者进行集成，请使用 [OpenID Connect 开发人员工具](https://openid.net/certified-open-id-developer-tools/)。

在使用 Amazon Cognito 进行身份验证和授权之前，请选择应用程序平台并准备代码以与服务集成。有关可用的平台 AWS SDKs，请参阅[使用进行身份验证 AWS SDKs](#amazon-cognito-authentication-with-sdks)。 AWS CLI 这是一款适用于 Amazon Cognito AWS 服务等的命令行软件开发工具包，是开始熟悉 Amazon Cognito API 操作及其语法的宝贵场所。

**注意**  
Amazon Cognito 的某些组件只能使用 API 进行配置。例如，您只能使用更新[或 [UpdateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UpdateUserPool.html)API 请求中[UserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_UserPoolType.html)类`LambdaConfig`属性的请求来设置用户池自定义 SMS 或电子邮件发件人](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-custom-sender-triggers.html) Lambda 触发器。[CreateUserPool](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateUserPool.html)

Amazon Cognito 用户池 API 与多个 API 操作类共享其命名空间。一个类配置用户池及其进程、身份提供者和用户。另一个类包括用户在公共客户端中执行的未经身份验证的操作，旨在登录、注销和管理他们的配置文件。最后一类 API 操作在机密的服务器端客户端中执行您使用自己的 AWS 凭据授权的用户操作。在开始实现应用程序代码之前，您必须知道您想要的应用程序架构。有关更多信息，请参阅 [了解 API、OIDC 和托管登录页面身份验证](authentication-flows-public-server-side.md#user-pools-API-operations)。

**Topics**
+ [使用进行身份验证 AWS Amplify](#cognito-integrate-apps-amplify)
+ [使用进行身份验证 AWS SDKs](#amazon-cognito-authentication-with-sdks)
+ [身份验证如何与 Amazon Cognito 配合使用](cognito-how-to-authenticate.md)
+ [将此服务与 AWS SDK 配合使用](sdk-general-information-section.md)
+ [使用 Amazon Verified Permissions 进行授权](amazon-cognito-authorization-with-avp.md)

## 使用进行身份验证 AWS Amplify
<a name="cognito-integrate-apps-amplify"></a>

AWS Amplify 是用于构建 Web 和移动应用程序的完整解决方案。借助 Amplify，您可以使用 Amplify 库连接到现有资源，也可以使用 Amplify 命令行界面（CLI）创建和配置新资源。Amplify 还连接了用户界面组件（如[身份验证器](https://ui.docs.amplify.aws/react/connected-components/authenticator)），以便在您的应用程序中设置和自定义登录和注册体验。

要在前端应用程序中使用 Amplify 身份验证功能，请参阅以下按平台分列的文档。
+ [适用于 React 的 Amplify 身份验证](https://docs.amplify.aws/react/start/)
+ [适用于 React Native 的 Amplify 身份验证](https://docs.amplify.aws/react-native/start/)
+ [适用于 Swift 的 Amplify 身份验证（iOS）](https://docs.amplify.aws/swift/start/)
+ [适用于 Android 的 Amplify 身份验证](https://docs.amplify.aws/android/start/)
+ [适用于 Flutter 的 Amplify 身份验证](https://docs.amplify.aws/flutter/start/)

Amplify 库是开源的，可在上使用。[GitHub](https://github.com/aws-amplify)要了解有关 Amplify Auth 如何实现 Amazon Cognito 身份验证的更多信息，请访问以下库。
+ [amplify-js](https://github.com/aws-amplify/amplify-js/tree/main/packages/auth)
+ [amplify-swift](https://github.com/aws-amplify/amplify-swift/tree/main/Amplify/Categories/Auth)
+ [amplify-flutter](https://github.com/aws-amplify/amplify-flutter/tree/main/packages/auth)
+ [amplify-android](https://github.com/aws-amplify/amplify-android/tree/main/aws-auth-cognito)

### 使用 Amplify 创建用户界面（UI）
<a name="cognito-integrate-apps-amplify-ui"></a>

[用户池托管登录](cognito-user-pools-managed-login.md)可以满足 Web 或移动应用程序的身份验证前端的基本需求。要在托管登录可容纳的参数之外自定义您的用户界面（UI），请自定义构建应用程序。[Amplify UI](https://ui.docs.amplify.aws/) 是各种语言的前端组件的可自定义集合。

![\[示例 Amplify 身份验证器应用程序的屏幕截图。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/amplify-authenticator-ui.png)


要开始使用您的自定义身份验证组件，请访问身份验证器组件的以下文档。
+ [适用于 Android 的身份验证器](https://ui.docs.amplify.aws/android/connected-components/authenticator)
+ [适用于 Angular 的身份验证器](https://ui.docs.amplify.aws/angular/connected-components/authenticator)
+ [适用于 Flutter 的身份验证器](https://ui.docs.amplify.aws/flutter/connected-components/authenticator)
+ [适用于 React 的身份验证器](https://ui.docs.amplify.aws/react/connected-components/authenticator)
+ [适用于 React Native 的身份验证器](https://ui.docs.amplify.aws/react-native/connected-components/authenticator)
+ [适用于 Swift 的身份验证器](https://ui.docs.amplify.aws/swift/connected-components/authenticator)
+ [适用于 Vue 的身份验证器](https://ui.docs.amplify.aws/vue/connected-components/authenticator)

## 使用进行身份验证 AWS SDKs
<a name="amazon-cognito-authentication-with-sdks"></a>

要使用安全的后端构建您自己的身份微服务以与 Amazon Cognito 交互，请使用您选择的语言版本的软件开发工具包连接到 Amazon Cognito 用户池和 Amazon Cognito 身份池 API。 AWS 

有关各个 API 操作的详细信息，请参阅 [Amazon Cognito 用户池 API 参考](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_Operations.html)和 [Amazon Cognito API 参考](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/Welcome.html)。这些文档包含 “[https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html#API_InitiateAuth_SeeAlso](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html#API_InitiateAuth_SeeAlso)” 章节，其中包含 SDKs在支持的平台中使用各种资源的资源。
+ [AWS 命令行界面](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/index.html#cli-aws-cognito-idp)
+ [AWS 适用于 .NET 的 SDK](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/CognitoIdentityProvider/TCognitoIdentityProviderClient.html)
+ [AWS 适用于 C\$1\$1 的 SDK](https://sdk.amazonaws.com/cpp/api/LATEST/aws-cpp-sdk-cognito-idp/html/class_aws_1_1_cognito_identity_provider_1_1_cognito_identity_provider_client.html)
+ [AWS 适用于 Go 的 SDK](https://docs.aws.amazon.com/sdk-for-go/api/service/cognitoidentityprovider/#CognitoIdentityProvider)
+ [AWS 适用于 Java 的 SDK V2](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cognitoidentityprovider/CognitoIdentityProviderClient.html)
+ [AWS 适用于 JavaScript](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityServiceProvider.html)
+ [AWS 适用于 PHP 的 SDK V3](https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.CognitoIdentityProvider.CognitoIdentityProviderClient.html)
+ [AWS Python 软件开发工具包](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cognito-idp.html)
+ [AWS 适用于 Ruby V3 的 SDK](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/CognitoIdentityProvider/Client.html)

# 身份验证如何与 Amazon Cognito 配合使用
<a name="cognito-how-to-authenticate"></a>

当您的客户登录 Amazon Cognito 用户池时，您的应用程序会收到 JSON 网络令牌 () JWTs。

当您的客户使用用户池令牌或其他提供商登录身份池时，您的应用程序将收到临时 AWS 证书。

通过用户池登录，您可以完全使用 AWS SDK 实现身份验证和授权。如果您不想构建自己的用户界面（UI）组件，则可以调用预构建的 Web UI（托管登录）或第三方身份提供者（IdP）的登录页面。

本主题概述了您的应用程序与 Amazon Cognito 交互以使用 ID 令牌进行身份验证、使用访问令牌进行授权以及使用身份池 AWS 服务 凭证进行访问的一些方式。

**Topics**
+ [使用托管登录进行用户池身份验证](#cognito-authentication-concepts-managed-login)
+ [使用 AWS SDK 进行用户池 API 身份验证和授权](#cognito-authentication-concepts-apiauth)
+ [使用第三方身份提供者进行用户池身份验证](#cognito-authentication-concepts-thirdparty)
+ [身份池身份验证](#cognito-authentication-concepts-identitypools)

## 使用托管登录进行用户池身份验证
<a name="cognito-authentication-concepts-managed-login"></a>

[托管登录](cognito-user-pools-managed-login.md)是一个链接到您的用户池和应用程序客户端的网站。使用它可为用户执行登录、注册和密码重置操作。如果应用程序具有托管登录组件，可用于身份验证，那么就可以减少开发人员实施应用程序所花的时间和精力。应用程序可以跳过进行身份验证的 UI 组件，并在用户的浏览器中调用托管登录网站。

应用程序 JWTs 通过网络或应用程序重定向位置收集用户。实施托管登录的应用程序可以连接到用户池进行身份验证，就好像它们是 OpenID Connect（OIDC）IdP 一样。

托管登录适合这样的模型：应用程序需要 OIDC 授权服务器的身份验证服务，但不立即需要自定义身份验证、身份池集成或用户属性自助服务等功能。当您想使用其中一些高级选项时，您可以使用 SDK 的用户池组件来实施。

托管登录和第三方 IdP 身份验证模型主要依赖 OIDC 的实现，最适合范围为 2.0 的高级授权模型。 OAuth 

以下示意图说明了托管登录身份验证的典型登录会话。

![\[一个流程图，展示了某个应用程序如何提示用户输入并使用托管登录进行登录。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/authentication-managed-login.png)


**托管登录身份验证流程**

1. 一个用户访问您的应用程序。

1. 他们选择“登录”链接。

1. 该应用程序将用户引导至用户池域的托管登录页面的登录提示处。

1. 他们输入用户名和密码。

1. 用户池验证用户的凭证，并确定用户具有已激活的多重身份验证（MFA）。

1. 托管登录页面提示用户输入 MFA 代码。

1. 用户输入他们的 MFA 代码。

1. 用户池将用户重定向到应用程序 URL。

1. 该应用程序从托管登录附加到[回调 URL](cognito-terms.md#term-callbackurl) 的 URL 请求参数收集授权代码。

1. 应用程序通过授权代码请求令牌。

1. 令牌端点返回 JWTs 到应用程序。

1. 应用程序解码、验证、存储或缓存用户的。 JWTs

1. 应用程序显示请求的访问控制组件。

1. 用户查看其内容。

1. 后来，用户的访问令牌过期，他们请求查看访问控制组件。

1. 应用程序确定用户的会话应该持续下去。应用程序使用刷新令牌从令牌端点请求新令牌。

**变体和自定义**  
您可以使用适用于整个用户池的[品牌编辑器](managed-login-brandingeditor.md)来自定义托管登录页面的外观，也可以在任何[应用程序客户端](cognito-terms.md#term-appclient)级别进行自定义。您还可以使用自己的身份提供者、范围、用户属性的访问权限和高级安全配置来[配置应用程序客户端](user-pool-settings-client-apps.md)。

**相关资源**
+ [用户池托管登录](cognito-user-pools-managed-login.md)
+ [作用域、M2M 和资源服务器](cognito-user-pools-define-resource-servers.md)
+ [用户池端点和托管登录参考](cognito-userpools-server-contract-reference.md)

## 使用 AWS SDK 进行用户池 API 身份验证和授权
<a name="cognito-authentication-concepts-apiauth"></a>

AWS 已在[各种开发者框架中为 Amazon Cognito 用户池或 *Amazon Cognito 身份*提供商开发了](cognito-integrate-apps.md#amazon-cognito-authentication-with-sdks)组件。其中内置的方法 SDKs 调用 [Amazon Cognito 用户池 API](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/Welcome.html)。同一个用户池 API 命名空间同时具有用于用户池配置和用户身份验证配置的操作。有关更全面的概述，请参阅[了解 API、OIDC 和托管登录页面身份验证](authentication-flows-public-server-side.md#user-pools-API-operations)。

API 身份验证适合您的应用程序具有现有 UI 组件且主要依赖用户池作为用户目录的模型。这种设计将 Amazon Cognito 添加为大型应用程序中的一个组件。该设计需要使用编程逻辑来处理复杂的质询和响应链。

此应用程序不需要实现完整的 OpenID Connect（OIDC）依赖方实施。相反，它具有解码和使用的 JWTs能力。如果您想访问[本地用户](cognito-terms.md#terms-localuser)的全套用户池特征，请在您的开发环境中使用 Amazon Cognito SDK 构建身份验证。

使用自定义 OAuth 作用域的 API 身份验证不太倾向于外部 API 授权。要通过 API 身份验证向访问令牌添加自定义范围，请在运行时使用 [令牌生成前 Lambda 触发器](user-pool-lambda-pre-token-generation.md) 修改令牌。

以下示意图说明了 API 身份验证的典型登录会话。

![\[一个流程图，显示一个应用程序，该应用程序提示用户输入并使用 S AWS DK 登录。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/authentication-api.png)


**API 身份验证流程**

1. 一个用户访问您的应用程序。

1. 他们选择“登录”链接。

1. 他们输入用户名和密码。

1. 应用程序调用发出 [InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)API 请求的方法。该请求会将用户的凭证传递到用户池。

1. 用户池验证用户的凭证，并确定用户具有已激活的多重身份验证（MFA）。

1. 用户池通过请求获取 MFA 代码的质询进行响应。

1. 应用程序会生成一个提示，指明从用户那里收集 MFA 代码。

1. 应用程序调用发出 [RespondToAuthChallenge](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_RespondToAuthChallenge.html)API 请求的方法。请求传递用户的 MFA 代码。

1. 用户池验证用户的 MFA 代码。

1. 用户池以用户池的回应 JWTs。

1. 应用程序解码、验证、存储或缓存用户的。 JWTs

1. 应用程序显示请求的访问控制组件。

1. 用户查看其内容。

1. 后来，用户的访问令牌过期，他们请求查看访问控制组件。

1. 应用程序确定用户的会话应该持续下去。它使用刷新令牌再次调用该[InitiateAuth](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)方法并检索新令牌。

**变体和自定义**  
您可以通过额外质询（例如，您自己的自定义身份验证质询）来增强此流程。您可以自动限制以下用户的访问权限：其密码已泄露的用户，或者表现出意料之外的特性，可能表明存在恶意登录尝试的用户。注册、更新用户属性和重置密码的操作流程大致相同。这些流程中的大多数都有重复的公共（客户端）和机密（服务器端）API 操作。

**相关资源**
+ [Amazon Cognito 用户池 API](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/Welcome.html)
+ [用户池入门](getting-started-user-pools.md)
+ [将 Amazon Cognito 身份验证和授权与 Web 和移动应用程序集成](cognito-integrate-apps.md)
+ [了解 API、OIDC 和托管登录页面身份验证](authentication-flows-public-server-side.md#user-pools-API-operations)

## 使用第三方身份提供者进行用户池身份验证
<a name="cognito-authentication-concepts-thirdparty"></a>

使用外部身份提供者（IdP）或*联合身份验证*进行登录的模型与[托管登录](#cognito-authentication-concepts-managed-login)类似。您的应用程序是用户池的 OIDC 依赖方，而您的用户池则充当 IdP 的传递方。IdP 可以是像 Facebook 或 Google 这样的使用者用户目录，也可以是像 Azure 这样的 SAML 2.0 或 OIDC 企业目录。

您的应用程序调用用户池[授权服务器](cognito-terms.md#term-authzserver)上的重定向端点，而不是用户浏览器中的托管登录。从用户的角度来看，他们是选择您的应用程序中的登录按钮。然后，他们的 IdP 提示他们登录。与托管登录身份验证一样，应用程序 JWTs 在应用程序的重定向位置收集。

使用第三方 IdP 进行身份验证适合这样的模型：用户在注册您的应用程序时可能不想使用新密码。对于已实施托管登录身份验证的应用程序，可以更轻松地添加第三方身份验证。实际上，由于您在用户浏览器中调用的内容略有不同，托管登录和第三方会 IdPs 产生一致的身份验证结果。

与托管登录身份验证一样，联合身份验证最适合范围为 OAuth 2.0 的高级授权模型。

以下示意图说明了联合身份验证的典型登录会话。

![\[一个流程图，展示了一个应用程序如何提示用户输入并通过第三方 IdP 来登录。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/authentication-federated.png)


**联合身份验证流程**

1. 一个用户访问您的应用程序。

1. 他们选择“登录”链接。

1. 应用程序将用户引导至其 IdP 的登录提示处。

1. 他们输入用户名和密码。

1. IdP 验证用户的凭证，并确定用户具有已激活的多重身份验证（MFA）。

1. IdP 会提示用户输入 MFA 代码。

1. 用户输入他们的 MFA 代码。

1. IdP 使用 SAML 响应或授权代码将用户重定向至用户池。

1. 如果用户传递了授权码，则用户池会静默地将该代码交换为 IdP 令牌。用户池会验证 IdP 令牌，并使用新的授权代码将用户重定向到应用程序。

1. 应用程序从用户池附加到[回调 URL](cognito-terms.md#term-callbackurl) 的 URL 请求参数收集授权代码。

1. 应用程序通过授权代码请求令牌。

1. 令牌端点返回 JWTs 到应用程序。

1. 应用程序解码、验证、存储或缓存用户的。 JWTs

1. 应用程序显示请求的访问控制组件。

1. 用户查看其内容。

1. 后来，用户的访问令牌过期，他们请求查看访问控制组件。

1. 应用程序确定用户的会话应该持续下去。应用程序使用刷新令牌从令牌端点请求新令牌。

**变体和自定义**  
您可以在[托管登录](#cognito-authentication-concepts-managed-login)中启动联合身份验证，用户可以从分配给[应用程序客户端 IdPs ](cognito-terms.md#term-appclient)的列表中进行选择。托管登录还会提示输入电子邮件地址，并[自动将用户的请求路由到](cognito-user-pools-managing-saml-idp-naming.md)相应的 SAML IdP。使用第三方身份提供者进行身份验证*不需要*用户与托管登录进行交互。您的应用程序可以向用户的[授权服务器请求](cognito-terms.md#term-authorizationserver)添加请求参数，并让用户静默地重定向到其 IdP 登录页面。

**相关资源**
+ [使用第三方身份提供者进行用户池登录](cognito-user-pools-identity-federation.md)
+ [作用域、M2M 和资源服务器](cognito-user-pools-define-resource-servers.md)
+ [用户池端点和托管登录参考](cognito-userpools-server-contract-reference.md)

## 身份池身份验证
<a name="cognito-authentication-concepts-identitypools"></a>

身份池是您应用程序中的一个组件，其功能、API 命名空间和 SDK 模型与用户池有所不同。用户池提供基于令牌的身份验证和授权，而身份池则为 AWS Identity and Access Management (IAM) 提供授权。

您可以将一组分配 IdPs 给身份池，并使用这些身份池登录用户。用户池作为身份池紧密集成 IdPs ，为身份池提供了最多的访问控制选项。同时，身份池有多种身份验证选项可供选择。用户池加入 SAML、OIDC、社交、开发者和访客身份源，作为从身份池中获得临时 AWS 证书的路由。

身份池的身份验证是外部的，它遵循前面说明的其中一个用户池流程，或者您与另一个 IdP 独立开发的流程。在您的应用程序执行初始身份验证后，它会将证明传递给身份池并收到一个临时会话作为返回。

使用身份池进行身份验证适合您使用 IAM 授权对应用程序资产和数据实施访问控制 AWS 服务 的模式。与[用户池中的 API 身份验证](#cognito-authentication-concepts-apiauth)一样，成功的应用程序包括 AWS SDKs 您想要访问的每项服务，以使用户受益。 AWS SDKs 将身份池身份验证中的凭据作为签名应用于 API 请求。

以下示意图说明了使用 IdP 的身份池身份验证的典型登录会话。

![\[一个流程图，展示了一个应用程序如何提示用户输入并通过第三方 IdP 来登录。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/authentication-identity-pool.png)


**身份池身份验证流程**

1. 一个用户访问您的应用程序。

1. 他们选择“登录”链接。

1. 应用程序将用户引导至其 IdP 的登录提示处。

1. 他们输入用户名和密码。

1. IdP 验证用户的凭证。

1. IdP 将用户重定向至具有 SAML 响应或授权代码的应用程序。

1. 如果用户传递了授权代码，则应用程序会将该代码交换为 IdP 令牌。

1. 应用程序解码、验证、存储或缓存用户或断言。 JWTs 

1. 应用程序调用发出 [GetId](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetId.html)API 请求的方法。应用程序传递用户的令牌或断言并请求身份 ID。

1. 身份池根据配置的身份提供者验证令牌或断言。

1. 身份池返回身份 ID。

1. 应用程序调用发出 [GetCredentialsForIdentity](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetCredentialsForIdentity.html)API 请求的方法。应用程序传递用户的令牌或断言并请求 IAM 角色。

1. 身份池会生成一个新的 JWT。新的 JWT 包含请求 IAM 角色的声明。身份池根据用户的请求和 IdP 的身份池配置中的角色选择标准来确定角色。

1. AWS Security Token Service (AWS STS) 响应来自身份池的[AssumeRoleWithWebIdentity](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html)请求。响应包含使用 IAM 角色进行临时会话的 API 凭证。

1. 应用程序存储会话凭证。

1. 用户在需要 AWS中的访问受保护资源的应用程序中执行操作。

1. 应用程序将临时证书作为[签名](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-signing.html)应用于所需的 API 请求 AWS 服务。

1. IAM 评估凭证中附加到该角色的策略。并将策略与请求进行比较。

1.  AWS 服务 返回请求的数据。

1. 应用程序在用户的界面中呈现数据。

1. 用户查看数据。

**变体和自定义**  
要使用用户池来可视化身份验证，请在**发放令牌/断言**步骤之后插入其中一个之前的用户池概述。开发人员身份验证将**请求身份**之前的所有步骤替换为由[开发人员凭证](cognito-terms.md#term-developercredentials)签名的请求。访客身份验证还会直接跳到**请求身份**步骤，不验证身份验证，并返回 [limited-access](iam-roles.md#access-policies-scope-down-services) IAM 角色的凭证。

**相关资源**
+ [Amazon Cognito 身份池](cognito-identity.md)
+ [用户 IAM 角色](identity-pools.md#user-iam-roles)
+ [身份池身份验证流程](authentication-flow.md)

# 将此服务与 AWS SDK 配合使用
<a name="sdk-general-information-section"></a>

AWS 软件开发套件 (SDKs) 可用于许多流行的编程语言。每个软件开发工具包都提供 API、代码示例和文档，使开发人员能够更轻松地以其首选语言构建应用程序。


| SDK 文档 | 代码示例 | 
| --- | --- | 
| [适用于 C\$1\$1 的 AWS SDK](https://docs.aws.amazon.com/sdk-for-cpp) | [适用于 C\$1\$1 的 AWS SDK 代码示例](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp) | 
| [AWS CLI](https://docs.aws.amazon.com/cli) | [AWS CLI 代码示例](https://docs.aws.amazon.com/code-library/latest/ug/cli_2_code_examples.html) | 
| [适用于 Go 的 AWS SDK](https://docs.aws.amazon.com/sdk-for-go) | [适用于 Go 的 AWS SDK 代码示例](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/gov2) | 
| [适用于 Java 的 AWS SDK](https://docs.aws.amazon.com/sdk-for-java) | [适用于 Java 的 AWS SDK 代码示例](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2) | 
| [适用于 JavaScript 的 AWS SDK](https://docs.aws.amazon.com/sdk-for-javascript) | [适用于 JavaScript 的 AWS SDK 代码示例](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javascriptv3) | 
| [适用于 Kotlin 的 AWS SDK](https://docs.aws.amazon.com/sdk-for-kotlin) | [适用于 Kotlin 的 AWS SDK 代码示例](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin) | 
| [适用于 .NET 的 AWS SDK](https://docs.aws.amazon.com/sdk-for-net) | [适用于 .NET 的 AWS SDK 代码示例](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3) | 
| [适用于 PHP 的 AWS SDK](https://docs.aws.amazon.com/sdk-for-php) | [适用于 PHP 的 AWS SDK 代码示例](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/php) | 
| [AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell) | [AWS Tools for PowerShell 代码示例](https://docs.aws.amazon.com/code-library/latest/ug/powershell_5_code_examples.html) | 
| [适用于 Python (Boto3) 的 AWS SDK](https://docs.aws.amazon.com/pythonsdk) | [适用于 Python (Boto3) 的 AWS SDK 代码示例](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/python) | 
| [适用于 Ruby 的 AWS SDK](https://docs.aws.amazon.com/sdk-for-ruby) | [适用于 Ruby 的 AWS SDK 代码示例](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/ruby) | 
| [适用于 Rust 的 AWS SDK](https://docs.aws.amazon.com/sdk-for-rust) | [适用于 Rust 的 AWS SDK 代码示例](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/rustv1) | 
| [适用于 SAP ABAP 的 AWS SDK](https://docs.aws.amazon.com/sdk-for-sapabap) | [适用于 SAP ABAP 的 AWS SDK 代码示例](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/sap-abap) | 
| [适用于 Swift 的 AWS SDK](https://docs.aws.amazon.com/sdk-for-swift) | [适用于 Swift 的 AWS SDK 代码示例](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/swift) | 

**示例可用性**  
找不到所需的内容？ 通过使用此页面底部的**提供反馈**链接请求代码示例。

# 使用 Amazon Verified Permissions 进行授权
<a name="amazon-cognito-authorization-with-avp"></a>

[Amazon Verified Permissions](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/what-is-avp.html) 是针对您构建的应用程序的授权服务。当您将 Amazon Cognito 用户池添加为身份源时，应用程序可以将用户池访问权限或身份（ID）令牌传递给 Verified Permissions，以便做出允许或拒绝决定。Verified Permissions 根据您使用 [Cedar 策略语言](https://docs.cedarpolicy.com/)编写的策略，来考虑用户的属性和请求上下文。请求上下文可以包括所请求的文档、映像或其他资源的标识符，以及用户想要对该资源采取的操作。

您的应用程序可以在或 [BatchIsAuthorizedWithToken](https://docs.aws.amazon.com/verifiedpermissions/latest/apireference/API_BatchIsAuthorizedWithToken.html)API 请求中向已验证的权限提供用户的身份[IsAuthorizedWithToken](https://docs.aws.amazon.com/verifiedpermissions/latest/apireference/API_IsAuthorizedWithToken.html)或访问令牌。这些 API 操作接受您的用户作为 `Principal` 并对他们想要访问的 `Resource` 上的 `Action` 作出授权决策。使用额外的自定义 `Context` 有助于作出细致的访问决策。

当应用程序在 `IsAuthorizedWithToken` API 请求中提供令牌时，Verified Permissions 将执行以下验证。

1. 您的用户池是针对所请求的策略存储而配置的 Verified Permissions [身份来源](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/identity-providers.html)。

1. 访问令牌或身份令牌中的 `client_id` 或 `aud` 声明分别与您提供给 Verified Permissions 的用户池应用程序客户端 ID 相匹配。要验证此声明，您必须在 Verified Permissions 身份来源中[配置客户端 ID 验证](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/cognito-validation.html)。

1. 您的令牌未过期。

1. 您的令牌中 `token_use` 声明的值与您传递给 `IsAuthorizedWithToken` 的参数相匹配。如果您将 `token_use` 声明传递给 `accessToken` 参数，则该声明必须是 `access`，并且如果将它传递给 `identityToken` 参数，则声明必须是 `id`。

1. 令牌中的签名来自用户池中已发布的 JSON 网络密钥 (JWKs)。你可以在 JWKs at 中查看你的`https://cognito-idp.Region.amazonaws.com/your user pool ID/.well-known/jwks.json`。

**已撤销的令牌和已删除的用户**  
Verified Permissions 仅验证它从您的身份来源和用户令牌到期时间所了解的信息。Verified Permissions 不检查令牌是否撤销或用户是否存在。如果您从用户池中撤销了用户的令牌或删除了用户的配置文件，则 Verified Permissions 在令牌到期之前仍会认为该令牌有效。

**策略评估**  
将您的用户池配置为[策略存储](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/terminology.html#term-policy-store)的[身份来源](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/identity-providers.html)。将您的应用程序配置为在对 Verified Permissions 的请求中提交用户的令牌。对于每个请求，Verified Permissions 将令牌中的声明与策略进行比较。Verified Permissions 策略类似于 AWS中的 IAM policy。该策略会声明*主体*、*资源* 和*操作*。如果您对于 `Allow` 的请求与允许的操作匹配，但与显式 `Deny` 操作不匹配，则 Verified Permissions 将对您的请求进行响应；否则，它将以 `Deny` 进行响应。有关更多信息，请参阅《Amazon Verified Permissions 用户指南》**中的 [Amazon Verified Permissions 策略](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/policies.html)。

**自定义令牌**  
要更改、添加和删除您想要向 Verified Permissions 提供的用户声明，请使用[令牌生成前 Lambda 触发器](user-pool-lambda-pre-token-generation.md)自定义访问令牌和身份令牌中的内容。使用令牌生成前触发器，您可以在令牌中添加和修改声明。例如，您可以在数据库中查询其他用户属性，并将这些属性编码为您的 ID 令牌。

**注意**  
由于 Verified Permissions 处理声明的方式，请勿在令牌生成前函数中添加名为 `cognito`、`dev` 或 `custom` 的声明。如果您提供的这些保留的声明前缀不是采用以冒号分隔的格式（例如 `cognito:username`），而是采用完整的声明名称，则您的授权请求会失败。

**其他资源**
+ [将 Amazon Cognito 令牌映射到 Verified Permissions 架构](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/identity-sources_map-token-to-schema.html)
+ [ APIs 使用亚马逊验证权限和亚马逊 Cognito 授权 API Gateway](https://aws.amazon.com/blogs/security/authorize-api-gateway-apis-using-amazon-verified-permissions-and-amazon-cognito/)
+ [讲习会：使用 Amazon Cognito 和 Verified Permissions 进行身份验证和授权](https://catalog.workshops.aws/app-auth)

## 使用 Verified Permissions 进行 API 授权
<a name="amazon-cognito-authorization-with-avp-api-authorization"></a>

您的身份证或访问令牌可以使用经过验证的权限授权向后端 Amazon API Gateway REST APIs 发出的请求。您可以创建一个[策略存储](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/policy-stores.html)，其中包含指向您的用户池和 API 的直接链接。使用[通过 API Gateway 和身份源进行设置](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/policy-stores_create.html)起始选项时，Verified Permissions 会将用户池身份源添加到策略存储中，并向 API 添加 Lambda 授权方。当您的应用程序将用户池持有者令牌传递给 API 时，Lambda 授权方会调用 Verified Permissions。授权方将令牌作为主体来传递，将请求路径和方法作为操作来传递。

下图说明了使用 Verified Permissions 的 API Gateway API 的授权流程。有关详细明细，请参阅《Amazon Verified Permissions 用户指南》中[与 API 相关的策略存储](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/policy-stores_api-userpool.html)。

![\[一个示意图，说明了使用 Amazon Verified Permissions 进行 API 授权的流程。应用程序向 Amazon API Gateway API 发出请求。API 调用 Lambda 授权方。授权方向 Verified Permissions 发出 API 请求。Verified Permissions 检查令牌有效性并返回授权决定。\]](http://docs.aws.amazon.com/zh_cn/cognito/latest/developerguide/images/amazon-cognito-avp-use-case.png)


Verified Permissions 围绕[用户池组](cognito-user-pools-user-groups.md)构造 API 授权。由于 ID 和访问令牌都包含`cognito:groups`声明，因此您的策略存储可以在各种应用程序上下文 APIs 中为您管理基于角色的访问控制 (RBAC)。

### 选择策略存储设置
<a name="amazon-cognito-authorization-with-avp-api-authorization-token-type"></a>

在策略存储上配置身份源时，必须选择是要处理访问令牌还是 ID 令牌。此决定对策略引擎的运作方式非常重要。ID 令牌包含用户属性。[访问令牌包含用户访问控制信息：OAuth 范围。](cognito-user-pools-define-resource-servers.md)尽管两种令牌类型都有组成员资格信息，但我们通常建议使用 Verified Permissions 策略存储来进行基于角色的访问控制时使用访问令牌。访问令牌为组成员资格增加了范围，有助于授权决策。访问令牌中的声明成为授权请求中的[上下文](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/context.html)。

在将用户池配置为身份源时，还必须配置用户和组实体类型。实体类型是您可以在 Verified Permissions 策略中引用的主体、操作和资源标识符。策略存储中的实体可以具有*成员*关系，其中一个实体可以是*父*实体的成员。通过成员资格，您可以引用主体组、操作组和资源组。对于用户池组，您指定的用户实体类型必须是该组实体类型的成员。当您在 Verified Permissions 控制台中设置 [API 相关策略存储](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/policy-stores_api-userpool.html)或遵循**引导式设置**时，您的策略存储会自动建立这种父成员关系。

ID 令牌可以将 RBAC 与基于属性的访问权限控制（ABAC）结合使用。创建 [API 相关策略存储](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/policy-stores_api-userpool.html)后，您可以使用[用户属性](#amazon-cognito-authorization-with-avp-example-policy)*和*组成员资格来增强策略。ID 令牌中的属性声明成为授权请求中的[主体属性](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/policies_examples-abac.html)。您的策略可以根据主体属性作出授权决定。

您也可以将策略存储配置为接受与您提供的可接受应用程序客户端列表相匹配且具有 `aud` 或 `client_id` 声明的令牌。

### 基于角色的 API 授权的示例策略
<a name="amazon-cognito-authorization-with-avp-api-authorization-example"></a>

以下示例策略是通过为示[PetStore](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-from-example.html)例 REST API 设置已验证权限策略存储而创建的。

```
permit(
  principal in PetStore::UserGroup::"us-east-1_EXAMPLE|MyGroup",
  action in [ PetStore::Action::"get /pets", PetStore::Action::"get /pets/{petId}" ],
  resource
  );
```

在以下情况下，Verified Permissions 返回对您的应用程序的授权请求的 `Allow` 决定：

1. 您的应用程序在 `Authorization` 标头中传递了 ID 令牌或访问令牌作为持有者令牌。

1. 您的应用程序传递一个具有 `cognito:groups` 声明的令牌，其中包含字符串 `MyGroup`。

1. 例如，您的应用程序向 `https://myapi.example.com/pets` 或 `https://myapi.example.com/pets/scrappy` 发出 `HTTP GET` 请求。

## Amazon Cognito 用户的示例策略
<a name="amazon-cognito-authorization-with-avp-example-policy"></a>

您的用户池还可以在 API 请求以外的条件下生成向 Verified Permissions 发出的授权请求。您可以将应用程序中的任何访问控制决策提交到策略存储。例如，您可以在任何请求传输到网络之前，通过基于属性的访问控制来增强 Amazon DynamoDB 或 Amazon S3 的安全性，从而减少配额使用量。

以下示例使用 [Cedar 策略语言](https://docs.cedarpolicy.com/)，以允许通过一个用户池应用程序客户端进行身份验证的财务用户读写 `example_image.png`。John 是应用程序中的用户，他从应用程序客户端接收 ID 令牌，并在 GET 请求中将其传递到需要授权的 URL `https://example.com/images/example_image.png`。John 的 ID 令牌拥有用户池应用程序客户端 ID `1234567890example` 的 `aud` 声明。令牌生成前 Lambda 函数还插入了一个新声明 `costCenter`，对于 John 来说，值为 `Finance1234`。

```
permit (
   principal,
   actions in [ExampleCorp::Action::"readFile", "writeFile"],
   resource == ExampleCorp::Photo::"example_image.png"
)
when {
   principal.aud == "1234567890example" &&
   principal.custom.costCenter like "Finance*"
};
```

以下请求正文会导致 `Allow` 响应。

```
{
   "accesstoken": "[John's ID token]",
   "action": {
      "actionId": "readFile",
      "actionType": "Action"
   },
   "resource": {
      "entityId": "example_image.png",
      "entityType": "Photo"
   }
}
```

当您要在 Verified Permissions 策略中指定主体时，请使用以下格式：

```
permit (
   principal == [Namespace]::[Entity]::"[user pool ID]|[user sub]",
   action,
   resource
);
```

以下是 ID 为 `us-east-1_Example`（带有子项）的用户池中的用户或用户 ID 为 `973db890-092c-49e4-a9d0-912a4c0a20c7` 的用户的示例主体。

```
principal == ExampleCorp::User::"us-east-1_Example|973db890-092c-49e4-a9d0-912a4c0a20c7",
```

当您要在 Verified Permissions 策略中指定用户组时，请使用以下格式：

```
permit (
   principal in [Namespace]::[Group Entity]::"[Group name]",
   action,
   resource
);
```

**基于属性的访问控制**  
为您的应用程序提供经过验证的权限授权，以及[用于 AWS 凭证的 Amazon Cognito 身份池的访问控制](https://docs.aws.amazon.com/cognito/latest/developerguide/attributes-for-access-control.html)属性功能，都是基于属性的访问控制 (ABAC) 的形式。以下是 Verified Permissions 和 Amazon Cognito ABAC 的功能比较。在 ABAC 中，系统检查实体的属性，并根据您定义的条件做出授权决策。


| 服务 | 流程 | 结果 | 
| --- |--- |--- |
| Amazon Verified Permissions | 根据对用户池 JWT 的分析返回Allow或Deny决策。 | 根据 Cedar 策略评估，应用程序资源的访问成功或失败。 | 
| Amazon Cognito 身份池（用于访问控制的属性） | 根据用户的属性为其分配[会话标签](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)。IAM 策略条件可以检查标签Allow或Deny用户访问权限 AWS 服务。 | 带有 IAM 角色临时 AWS 证书的标记会话。 | 