特定于应用程序的应用程序客户端设置 - Amazon Cognito
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

特定于应用程序的应用程序客户端设置

用户池应用程序客户端是用户池中的一项配置,它与一个通过 Amazon Cognito 进行身份验证的移动或 Web 应用程序进行交互。应用程序客户端可以调用经过授权和未经身份验证的 API 操作,并读取或修改用户的部分或全部属性。您的应用程序必须在操作中向应用程序客户端表明自己的身份,才能注册、登录和处理忘记的密码。这些 API 请求必须包括使用应用程序客户端 ID 进行自我识别以及使用可选客户端密钥进行授权的机制。您必须确保任何应用程序客户端 ID 或密钥的安全,以便只有经过授权的客户端应用程序才能调用这些未经身份验证的操作。此外,如果您将应用程序配置为使用 Amazon 凭证签署经过身份验证的 API 请求,您必须保护您的凭证免受用户检查。

您可以为一个用户池创建多个应用程序。应用程序客户端可能链接到应用程序的代码平台,也可能链接到用户池中的单独租户。例如,您可以为服务器端应用程序和其他 Android 应用程序创建一个应用程序。每个应用程序都有各自的应用程序客户端 ID。

您可以在应用程序客户端级别应用以下用户池特征的设置:

应用程序客户端类型

在 Amazon Cognito 中创建应用程序客户端时,您可以根据标准 OAuth 客户端类型公有客户端机密客户端预填充选项。使用客户端密钥配置机密客户端 有关客户端类型的更多信息,请参阅 IETF RFC 6749 #2.1

公有客户端

公有客户端在浏览器或移动设备上运行。由于它没有可信的服务器端资源,所以它没有客户端密钥。

机密客户端

机密客户端拥有可以信任的服务器端资源,使用客户端密钥进行未经身份验证的 API 操作。该应用程序可在后端服务器上作为守护进程或 Shell 脚本运行。

客户端密钥

客户端机密或客户端密码是一个固定字符串,您的应用程序必须在发送到应用程序客户端的所有 API 请求中使用该字符串。您的应用程序客户端必须有客户端密钥才能执行 client_credentials 授权。有关更多信息,请参阅 IETF RFC 6749 #2.3.1

您在创建应用程序后无法更改密钥。如果要轮换密钥,您可以创建一个具备新私有密钥的新应用程序。您也可以删除应用程序,以便阻止使用该应用程序客户端 ID 的应用程序的访问。

注意

当您为应用程序类型选择传统的 Web 应用程序机对机应用程序选项时,Amazon Cognito 控制台会创建带有客户端密钥的应用程序客户端。选择这两个选项之一生成客户端密钥,或者使用 CreateUserPoolClient 以编程方式创建客户端,并将 GenerateSecret 设置为 true

您可以将机密客户端和客户端密钥用于公有应用程序。使用 Amazon CloudFront 代理添加传输中的 SECRET_HASH。有关更多信息,请参阅 Amazon 博客上的使用 Amazon CloudFront 代理保护 Amazon Cognito 的公共客户端

JSON Web 令牌

Amazon Cognito 应用程序客户端可以发放以下类型的 JSON Web 令牌(JWT)。

身份(ID)令牌

一份可验证的声明,表明您的用户是从用户池进行的身份验证。OpenID Connect(OIDC)在 OAuth 2.0 定义的访问和刷新令牌标准中添加了 ID 令牌规范。ID 令牌包含身份信息,例如用户属性,您的应用程序可以使用这些信息来创建用户个人资料和配置资源。请参阅了解身份(ID)令牌了解更多信息。

访问令牌

您的用户访问权限的可验证声明。访问令牌包含范围,这是 OIDC 和 OAuth 2.0 的一项特征。您的应用程序可以为后端资源提供范围,并证明您的用户池已授权用户或计算机访问来自 API 的数据或它们自己的用户数据。具有自定义范围的访问令牌(通常来自 M2M 客户端凭证授权)用于授权访问资源服务器。请参阅了解访问令牌了解更多信息。

刷新令牌

一种加密的初始身份验证声明,当您的用户令牌到期时,您的应用程序可以将其提供给您的用户池。刷新令牌请求会返回新的未到期访问令牌和 ID 令牌。请参阅刷新令牌了解更多信息。

您可以在 Amazon Cognito 控制台中,从用户池的应用程序客户端菜单为每个应用程序客户端设置这些令牌的到期时间。

应用程序客户端术语

以下术语是 Amazon Cognito 控制台中应用程序客户端的可用属性。

允许回调 URL

回调 URL 指示在用户成功登录之后将被重新导向到哪里。选择至少一个回调 URL。回调 URL 必须:

  • 是绝对 URI。

  • 已预先向客户端注册。

  • 不包含片段组件。

请参阅 OAuth 2.0 – 重新导向端点

Amazon Cognito 要求使用 HTTPS 而不是 HTTP,但 http://localhost(仅用于测试目的)除外。

应用程序回调 URL(如 myapp://example)也受支持。

允许注销 URL

注销 URL 指示在您的用户注销后会被重定向到哪里。

属性读取和写入权限

您的用户池可能有许多客户,每个客户都有自己的应用程序客户端和 IdP。您可以将应用程序客户端配置为仅对与应用程序相关的用户属性具有读写权限。在机器对机器(M2M)授权等情况下,您可以不授予对任何用户属性的访问权限。

属性读取和写入权限配置的注意事项
  • 如果您创建应用程序客户端但不自定义属性读取和写入权限,Amazon Cognito 会向所有用户池属性授予读写权限。

  • 您可以授予对不可变自定义属性的写入权限。创建或注册用户时,您的应用程序客户端可以将值写入不可变属性。此后,您将无法为用户的任何不可变自定义属性写入值。

  • 应用程序客户端必须拥有对用户池中必要属性的写入权限。Amazon Cognito 控制台会自动将必要属性设置为可写属性。

  • 您不能允许应用程序客户端对 email_verifiedphone_number_verified 拥有写入权限。用户池管理员可以修改这些值。用户只能通过属性验证来更改这些属性的值。

身份验证流程

您的应用程序客户端允许的登录方法。您的应用程序可以支持通过用户名和密码、电子邮件和短信消息 OTP、通行密钥身份验证器、使用 Lambda 触发器的自定义身份验证以及令牌刷新进行身份验证。作为最佳安全实践,请在自定义构建的应用程序中使用 SRP 身份验证进行用户名和密码身份验证。

自定义范围

自定义范围是您在资源服务器中为自己的资源服务器定义的范围。格式为:资源-服务器-标识符/范围。请参阅范围、M2M 和带资源服务器的 API

默认的重定向 URI

将用户身份验证请求中的 redirect_uri 参数替换为第三方 IdP。使用 CreateUserPoolClientUpdateUserPoolClient API 请求的 DefaultRedirectURI 参数配置此应用程序客户端设置。此 URL 还必须是应用程序客户端的 CallbackURLs 的成员。在以下情况下,Amazon Cognito 会将经过身份验证的会话重定向到此 URL:

  1. 您的应用程序客户端分配了一个身份提供者并定义了多个回调 URL。如果身份验证请求不包括 redirect_uri 参数,则用户池会将对授权服务器的身份验证请求重定向到默认的重定向 URI。

  2. 应用程序客户端分配了一个身份提供者并定义了一个回调 URL。在这种情况下,无需定义默认的回调 URL。不包括 redirect_uri 参数的请求会重定向到一个可用的回调 URL。

身份提供者

您可以选择部分或全部用户池外部身份提供者(IDP)来对用户进行身份验证。您的应用程序客户端还可以仅对用户池中的本地用户进行身份验证。当您将 IdP 添加到应用程序客户端时,可以生成指向 IdP 的授权链接,并将其显示在您的托管登录的登录页面上。您可以分配多个 IdP,但必须至少分配一个。有关使用外部 IdP 的更多信息,请参阅使用第三方身份提供者进行用户池登录

OpenID Connect 范围

选择以下一个或多个 OAuth 范围来指定可以为访问令牌请求的访问权限。

  • openid 范围声明您要检索 ID 令牌和用户的唯一 ID。它还会请求全部或部分用户属性,具体取决于请求中的其他范围。除非您请求 openid 范围,否则 Amazon Cognito 不会返回 ID 令牌。openid 范围授权结构化 ID 令牌声明,例如过期时间和密钥 ID,并确定您在 userInfo 端点 的响应中收到的用户属性。

    • openid 是您请求的唯一范围时,Amazon Cognito 会使用当前应用程序客户端可以读取的所有用户属性填充 ID 令牌。对仅具有此范围的访问令牌的 userInfo 响应将返回所有用户属性。

    • 当您使用其他范围(例如 phoneemailprofile)请求 openid 时,ID 令牌和 userInfo 返回用户的唯一 ID 以及由其他范围定义的属性。

  • phone 范围授予对 phone_numberphone_number_verified 声明的访问权限。此范围只能通过 openid 范围来请求。

  • email 范围授予对 emailemail_verified 声明的访问权限。此范围只能通过 openid 范围来请求。

  • aws.cognito.signin.user.admin 范围授权对需要访问令牌的 Amazon Cognito 用户池 API 操作的访问权限,例如 UpdateUserAttributesVerifyUserAttribute

  • profile 范围授予对客户端可读取的所有用户属性的访问权限。此范围只能通过 openid 范围来请求。

有关范围的更多信息,请参阅标准 OIDC 范围列表。

OAuth 授权类型

OAuth 授权是一种检索用户池令牌的身份验证方法。Amazon Cognito 支持以下类型的授权。要将这些 OAuth 授权集成到您的应用程序中,您必须将域添加到您的用户池中。

授予授权代码

授权码授权会生成一个代码,您的应用程序可以用它与令牌端点交换用户池令牌。当您交换授权码时,您的应用程序会收到 ID、访问权限和刷新令牌。这种 OAuth 流程与隐式授权一样,都是在用户的浏览器中进行的。授权码授权是 Amazon Cognito 提供的最安全的授权,因为令牌在用户的会话中不可见。相反,您的应用程序会生成返回令牌的请求,并可以将其缓存在受保护存储空间中。有关更多信息,请参阅 IETF RFC 6749 #1.3.1 中的授权码

注意

作为公共客户端应用程序的最佳安全实践,只激活授权码授权 OAuth 流程,并实施代码交换证明密钥(PKCE)以限制令牌交换。通过 PKCE,客户端只有在向令牌端点提供与原始身份验证请求中相同的机密时,才能交换授权码。有关 PKCE 的更多信息,请参阅 IETF RFC 7636

隐式授予

隐式授权直接从对端点授权向用户的浏览器会话提供访问权限和 ID 令牌,但不返回刷新令牌。隐式授权消除了向令牌端点提出单独请求的要求,但与 PKCE 不兼容,也不会返回刷新令牌。该授权适用于无法完成授权码授权的测试场景和应用程序架构。有关更多信息,请参阅 IETF RFC 6749 #1.3.2 中的隐式授权。您可以在应用程序客户端中同时激活授权码授权和隐式授权,然后按需使用每个授权。

客户端凭证授权

客户端凭证授权在机器到机器的通信中使用。授权码和隐式授权向经过身份验证的人类用户发放令牌。客户端凭证授权非交互式系统对 API 的基于范围的授权。您的应用程序可以直接从令牌端点请求客户端凭证并接收访问令牌。有关更多信息,请参阅 IETF RFC 6749 #1.3.4 中的客户端凭证。您只能在具有客户端机密且不支持授权码或隐式授权的应用程序客户端中激活客户端凭证授权。

注意

由于您没有以用户身份调用客户端凭证流程,因此该授权只能向访问令牌添加自定义范围。自定义范围就是您为自己的资源服务器定义的范围。默认范围(例如 openidprofile)不适用于非人类用户。

由于 ID 令牌是对用户属性的验证,因此它们与 M2M 通信无关,客户凭证授权也不会发放 ID 令牌。请参阅范围、M2M 和带资源服务器的 API

客户端凭证授予会增加您的 Amazon 账单成本。有关更多信息,请参阅 Amazon Cognito 定价

创建应用程序客户端

Amazon Web Services 管理控制台
创建应用程序客户端(控制台)
  1. 转到 Amazon Cognito 控制台。如果出现提示,请输入 Amazon 凭证。

  2. 选择用户池

  3. 从列表中选择一个现有用户池,或创建一个用户池。这两个选项都会提示您使用特定于应用程序的设置配置应用程序客户端。

  4. 选择一种能反映您的应用程序架构的应用程序类型

  5. 使用友好的标识符命名您的应用程序

  6. 输入返回 URL

  7. 选择创建应用程序客户端。创建应用程序客户端后,您可以更改高级选项。

  8. Amazon Cognito 将您返回到应用程序客户端详细信息。要访问应用程序的示例代码,请从快速设置指南选项卡中选择一个平台。

Amazon CLI
aws cognito-idp create-user-pool-client --user-pool-id MyUserPoolID --client-name myApp
注意

回调和注销 URL 采用 JSON 格式,以防止 CLI 将它们视为远程参数文件:

--callback-urls "["https://example.com"]" --logout-urls "["https://example.com"]"

请参阅 Amazon CLI 命令参考了解更多信息:create-user-pool-client

Amazon Cognito user pools API

生成一个 CreateUserPoolClient API 请求。必须为所有您不想设置为默认值的参数指定一个值。

更新用户池应用程序客户端(Amazon CLI 和 Amazon API)

在 Amazon CLI 中,输入以下命令:

aws cognito-idp update-user-pool-client --user-pool-id "MyUserPoolID" --client-id "MyAppClientID" --allowed-o-auth-flows-user-pool-client --allowed-o-auth-flows "code" "implicit" --allowed-o-auth-scopes "openid" --callback-urls "["https://example.com"]" --supported-identity-providers "["MySAMLIdP", "LoginWithAmazon"]"

如果命令成功,则 Amazon CLI 会返回确认:

{ "UserPoolClient": { "ClientId": "MyClientID", "SupportedIdentityProviders": [ "LoginWithAmazon", "MySAMLIdP" ], "CallbackURLs": [ "https://example.com" ], "AllowedOAuthScopes": [ "openid" ], "ClientName": "Example", "AllowedOAuthFlows": [ "implicit", "code" ], "RefreshTokenValidity": 30, "AuthSessionValidity": 3, "CreationDate": 1524628110.29, "AllowedOAuthFlowsUserPoolClient": true, "UserPoolId": "MyUserPoolID", "LastModifiedDate": 1530055177.553 } }

请参阅 Amazon CLI 命令参考了解更多信息:update-user-pool-client

Amazon API:UpdateUserPoolClient

获取有关用户池应用程序客户端的信息(Amazon CLI 和 Amazon API)

aws cognito-idp describe-user-pool-client --user-pool-id MyUserPoolID --client-id MyClientID

请参阅 Amazon CLI 命令参考了解更多信息:describe-user-pool-client

Amazon API:DescribeUserPoolClient

列出一个用户池中所有应用程序客户端的信息(Amazon CLI 和 Amazon API)

aws cognito-idp list-user-pool-clients --user-pool-id "MyUserPoolID" --max-results 3

请参阅 Amazon CLI 命令参考了解更多信息:list-user-pool-clients

Amazon API:ListUserPoolClients

删除用户池应用程序客户端(Amazon CLI 和 Amazon API)

aws cognito-idp delete-user-pool-client --user-pool-id "MyUserPoolID" --client-id "MyAppClientID"

请参阅 Amazon CLI 命令参考了解更多信息:delete-user-pool-client

Amazon API:DeleteUserPoolClient