范围、M2M 和带资源服务器的 API
在为用户池配置域后,Amazon Cognito 会自动预置一个 OAuth 2.0 授权服务器和托管 Web UI,其中包含您的应用程序可提供给用户的注册页和登录页。有关更多信息,请参阅 用户池托管登录。您可以选择希望授权服务器添加到访问令牌中的范围。范围授权访问资源服务器和用户数据。
资源服务器是 OAuth 2.0 API 服务器。为了保护受访问权限保护的资源,它会验证用户池中的访问令牌所包含的范围是否授权所请求的方法和它所保护的 API 中的路径。它根据令牌签名验证发放者,根据令牌到期时间验证有效性,并根据令牌声明中的范围验证访问级别。用户池范围位于访问令牌 scope 声明中。有关 Amazon Cognito 访问令牌中的声明的更多信息,请参阅了解访问令牌。
借助 Amazon Cognito,访问令牌中的范围可以授权访问外部 API 或用户属性。您可以向本地用户、联合用户或计算机身份发放访问令牌。
API 授权
以下一些方式可以使用 Amazon Cognito 令牌授权对 API 的请求:
- 访问令牌
-
将 Amazon Cognito 授权方添加到 REST API 方法请求配置时,将授权范围添加到授权方配置中。使用此配置,您的 API 会接受
Authorization标头中的访问令牌,并检查访问令牌中的可接受范围。 - ID 令牌
-
当您在 REST API 中将有效的 ID 令牌传递给 Amazon Cognito 授权方时,API Gateway 会接受请求并将 ID 令牌内容传递给 API 后端。
- Amazon Verified Permissions
-
在 Verified Permissions 中,您可以选择创建 API 关联策略存储。Verified Permissions 创建并分配一个 Lambda 授权方,该授权方处理请求
Authorization标头中的 ID 令牌或访问令牌。此 Lambda 授权方将您的令牌传递到策略存储,然后 Verified Permissions 将其与策略进行比较,并将向授权方返回允许或拒绝决定。
机器对机器(M2M)授权
Amazon Cognito 支持使用计算机身份访问 API 数据的应用程序。用户池中的计算机身份是在应用程序服务器上运行并连接到远程 API 的机密客户端。其操作无需用户交互:计划任务、数据流或资产更新。当这些客户端使用访问令牌授权其请求时,它们会执行机器对机器(M2M)授权。在 M2M 授权中,共享密钥取代访问控制中的用户凭证。
通过 M2M 授权访问 API 的应用程序必须具有客户端 ID 和客户端密钥。在您的用户池中,必须构建支持客户端凭证授予的应用程序客户端。要支持客户端凭证,您的应用程序客户端必须具有客户端密钥,且您必须有用户池域。在此流程中,您的计算机身份直接从 令牌端点 请求访问令牌。对于客户端凭证授予,您只能在访问令牌中授权来自资源服务器的自定义范围。有关设置应用程序客户端的更多信息,请参阅特定于应用程序的应用程序客户端设置。
来自客户端凭证授予的访问令牌实际上是一个可验证的声明,表明您希望计算机身份向 API 请求哪些操作。要详细了解访问令牌如何授权 API 请求,请继续阅读。有关示例应用程序,请参阅使用 Amazon CDK 进行基于 Amazon Cognito 和 API Gateway 的机器到机器授权
M2M 授权的计费模式不同于每月活跃用户(MAU)的计费方式。用户身份验证会根据每个活跃用户的数量收取费用,而 M2M 计费则反映了活跃的客户端凭证应用程序客户端和令牌请求总量。有关更多信息,请参阅 Amazon Cognito 定价
若要了解如何优化会在 Amazon 账单中增加费用的 Amazon Cognito 操作,请参阅管理成本。
机器对机器(M2M)客户端凭证的客户端元数据
您可以在 M2M 请求中传递客户端元数据。客户端元数据是来自用户或应用程序环境的附加信息,可影响令牌生成前 Lambda 触发器的结果。在涉及用户主体的身份验证操作中,您可以在 AdminRespondToAuthChallenge 和 RespondToAuthChallenge API 请求的请求正文中,将客户端元数据传递给令牌生成前触发器。由于应用程序通过直接向 令牌端点 发出请求来执行为 M2M 生成访问令牌的流程,因此它们的模型不同。在客户端凭证令牌请求的 POST 正文中,传递一个 aws_client_metadata 参数,其值为客户端元数据对象经 URL 编码(x-www-form-urlencoded)后的字符串。有关示例请求,请参阅基本授权的客户端凭证。以下是传递键值对 {"environment": "dev", "language": "en-US"} 的参数的示例。
aws_client_metadata=%7B%22environment%22%3A%20%22dev%22,%20%22language%22%3A%20%22en-US%22%7D
关于范围
范围是应用程序可请求的对资源的访问权限的级别。在 Amazon Cognito 访问令牌中,范围由您与用户池建立的信任提供支持:一个具有已知数字签名的可信访问令牌发放者。用户池可以生成访问令牌,其范围可以证明您的客户可以管理自己的部分或全部用户个人资料,或者可以从后端 API 检索数据。Amazon Cognito 用户池使用用户池预留 API 范围、自定义范围和 OpenID Connect(OIDC)范围来发放访问令牌。
用户池预留 API 范围
Amazon Cognito 用户池 API 中的 aws.cognito.signin.user.admin 范围授权当前用户执行自助操作。它授权访问令牌持有者使用 GetUser 和 UpdateUserAttributes API 等操作来查询和更新有关持有者的所有信息。当您使用 Amazon Cognito 用户池 API 对用户进行身份验证时,这是您在访问令牌中收到的唯一范围。这也是您读写已授权应用程序客户端读写的用户属性所需的唯一范围。您也可以在发往 对端点授权 的请求中请求此范围。仅此范围不足以向 userInfo 端点 请求用户属性。对于同时授权用户池 API 和 用户 userInfo 请求的访问令牌,您必须在一个 /oauth2/authorize 请求中同时请求 openid 和 aws.cognito.signin.user.admin 这两个范围。
自定义范围
自定义范围授权对资源服务器所保护的外部 API 的请求。您可以使用其他类型的范围请求自定义范围。您可以在此页面中找到有关自定义范围的更多信息。
OpenID Connect(OIDC)范围
使用用户池授权服务器(包括托管登录)验证用户身份时,必须请求范围。您可以在 Amazon Cognito 授权服务器中对用户池本地用户和第三方联合用户进行身份验证。OIDC 范围授权您的应用从您的用户池的 userInfo 端点 中读取用户信息。在 OAuth 模型中,您可以从 userInfo 端点查询用户属性,从而优化您的应用程序,使其能够处理大量的用户属性请求。userInfo 端点返回权限级别的属性,该级别由访问令牌中的范围决定。您可以授权您的应用程序客户端颁发具有以下 OIDC 范围的访问令牌。
- openid
-
OpenID Connect (OIDC) 查询的最小范围。授权 ID 令牌、唯一标识符声明
sub以及请求其他范围的能力。注意
当您请求
openid范围而不请求其他范围时,您的用户池 ID 令牌和userInfo响应将包括您的应用程序客户端可以读取的所有用户属性的声明。当您同时请求openid和其他 OIDC 范围(例如profile、email和phone)时,ID 令牌和 userInfo 响应的内容将受到其他范围的限制。例如,如果发送到 对端点授权 的请求带有参数
scope=openid+email,则将返回带有sub、email和email_verified的 ID 令牌。来自此请求的访问令牌也将从 userInfo 端点 返回这些属性。带有参数scope=openid的请求将在 ID 令牌中返回所有客户端可以读取的属性,userInfo响应也是如此。 - 配置文件
-
授权应用程序客户端可以读取的所有用户属性。
- 电子邮件
-
授权用户属性
email和email_verified。如果有已明确设置的值,Amazon Cognito 将返回email_verified。 - phone
-
授权用户属性
phone_number和phone_number_verified。
关于资源服务器
资源服务器 API 可能会授予对数据库中信息的访问权限,或者控制您的 IT 资源。Amazon Cognito 访问令牌可以授权访问支持 OAuth 2.0 的 API。Amazon API Gateway REST API 具有对使用 Amazon Cognito 访问令牌进行授权的内置支持。应用程序会将 API 调用中的访问令牌传递到资源服务器。资源服务器将检查访问令牌以确定是否应授予访问权限。
Amazon Cognito 将来可能会更新用户池访问令牌的架构。如果您的应用程序在将访问令牌传递给 API 之前分析其内容,则您必须对代码进行设计以接受架构的更新。
自定义范围由您定义,它会扩展用户池的授权功能,以包括与查询和修改用户及其属性无关的目的。例如,如果您有一个照片资源服务器,它可能会定义两个范围:photos.read 用于对照片的读取访问,photos.write 用于写入/删除访问。您可以配置 API 以接受用于授权的访问令牌,并授予 HTTP GET 请求使用 scope 声明中的 photos.read 访问令牌,以及授予 HTTP POST 请求使用 photos.write 访问令牌。这些是自定义范围。
注意
您的资源服务器在处理访问令牌内的任何声明之前必须验证访问令牌的签名和到期日期。有关验证令牌的更多信息,请参阅验证 JSON Web 令牌。有关在 Amazon API Gateway 中验证和使用用户池令牌的更多信息,请参阅博客将 Amazon Cognito 用户池与 API Gateway 集成
概览
利用 Amazon Cognito,您可以创建 OAuth2.0 资源服务器并将自定义范围与它们相关联。访问令牌中的自定义范围可向 API 中的特定操作授权。您可以授权用户池中的任何应用程序客户端从您的任何资源服务器发布自定义范围。将自定义范围与应用程序客户端相关联,并在来自令牌端点的 OAuth2.0 授权代码授予、隐式授予和客户端凭证授予中请求这些范围。Amazon Cognito 在访问令牌中将自定义范围添加到 scope 声明中。客户端可对其资源服务器使用访问令牌,然后服务器基于令牌中给出的范围做出授权决定。有关访问令牌范围的更多信息,请参阅将令牌与用户池结合使用。
要获得具有自定义范围的访问令牌,您的应用程序必须向 令牌端点 发出请求以兑换授权代码或请求客户端凭证授予。在托管登录中,您还可以通过隐式授予在访问令牌中请求自定义范围。
注意
因为它们是为以用户池作为 IdP 的人机交互式身份验证而设计的,所以,InitiateAuth 和 AdminInitiateAuth 请求在访问令牌中只使用单个值 aws.cognito.signin.user.admin 生成 scope 声明。
管理资源服务器和自定义范围
在创建资源服务器时,您必须提供资源服务器名称和资源服务器标识符。对于您在资源服务器中创建的每个范围,您都必须提供范围名称和描述。
-
资源服务器名称:资源服务器的易记名称,如
Solar system object tracker或Photo API。 -
资源服务器标识符:资源服务器的唯一标识符。标识符是您希望与 API 关联的任何名称,例如
solar-system-data。您可以配置更长的标识符,例如https://solar-system-data-api.example.com,作为对 API URI 路径的更直接引用,但较长的字符串会增加访问令牌的大小。 -
范围名称:
scope声明中需要的值。例如sunproximity.read。 -
描述:范围的友好描述。例如
Check current proximity to sun。
Amazon Cognito 可以在任何用户的访问令牌中包含自定义范围,无论这些用户是用户池的本地用户还是与第三方身份提供者的联合身份验证用户。在使用包含托管登录的 OAuth 2.0 授权服务器进行身份验证时,您可以为用户的访问令牌选择范围。您的用户的身份验证必须从以 scope 作为请求参数之一的对端点授权开始。以下是推荐的资源服务器格式。对于标识符,请使用 API 友好名称。对于自定义范围,请使用它们授权的操作。
resourceServerIdentifier/scopeName
例如,您在柯伊伯带发现了一颗新的小行星,您想通过 solar-system-data API 对其进行注册。授权对小行星数据库进行写操作的范围是 asteroids.add。当您请求授权您注册发现的小行星的访问令牌时,请将 scope HTTPS 请求参数格式设置为 scope=solar-system-data/asteroids.add。
从资源服务器中删除一个范围不会删除其与所有客户端的关联。而是范围标记为非活动。Amazon Cognito 不会为访问令牌添加非活动的范围,但如果您的应用程序请求访问令牌,则会正常进行。如果您稍后再次将范围添加到资源服务器,则 Amazon Cognito 会再次将其写入访问令牌。如果您请求的范围尚未与应用程序客户端关联,则无论您是否将其从用户池资源服务器中删除,身份验证都会失败。
您可以使用 Amazon Web Services 管理控制台、API 或 CLI 为您的用户池定义资源服务器和范围。
为您的用户池定义资源服务器(Amazon Web Services 管理控制台)
您可以使用 Amazon Web Services 管理控制台为您的用户池定义资源服务器。
定义资源服务器
-
在导航窗格中,选择用户池,然后选择要编辑的用户池。
-
选择品牌下的域菜单,然后找到资源服务器。
-
选择 Create a resource server(创建资源服务器)。
-
输入 Resource server name(资源服务器名称)。例如
Photo Server。 -
输入 Resource server identifier(资源服务器识符)。例如
com.example.photos。 -
输入您的资源的 Custom scopes(自定义范围),例如
read和write。 -
对于每个 Scope name(范围名称),输入一个 Description(描述),如
view your photos和update your photos。 -
选择创建。
您的自定义范围可以在域菜单资源服务器下的自定义范围列中查看。可以从应用程序下的应用程序客户端菜单为应用程序客户端启用自定义范围。选择应用程序客户端,找到登录页面,然后选择编辑。添加 Custom scopes(自定义范围),然后选择 Save changes(保存更改)。
为您的用户池定义资源服务器(Amazon CLI 和 Amazon API)
使用以下命令可为您的用户池指定资源服务器设置。
创建资源服务器
-
Amazon CLI:
aws cognito-idp create-resource-server -
Amazon API:CreateResourceServer
获取有关您的资源服务器设置的信息
-
Amazon CLI:
aws cognito-idp describe-resource-server -
Amazon API:DescribeResourceServer
列出用户池的所有资源服务器的相关信息
-
Amazon CLI:
aws cognito-idp list-resource-servers -
Amazon API:ListResourceServers
删除资源服务器
-
Amazon CLI:
aws cognito-idp delete-resource-server -
Amazon API:DeleteResourceServer
更新资源服务器的设置
-
Amazon CLI:
aws cognito-idp update-resource-server -
Amazon API:UpdateResourceServer
资源绑定
通过资源绑定(也称为资源指示器),您可以向用户池授权服务器请求特定于 API 的授权授予。资源绑定是 RFC 8707
注意
您只能为用户将访问令牌绑定到资源。您不能对客户端凭证 M2M 授予请求资源绑定。
当您对 Amazon Cognito 用户池使用资源绑定时,客户端可以在向您的用户池授权服务器发送的身份验证请求中包含一个 resource 参数。您的用户池验证所请求资源的值是否为 URL,遵循与应用程序客户端回调 URL 相同的方案规则:https://、仅带 localhost 的 http:// 或自定义方案(例如 myapp://)。Amazon Cognito 在访问令牌的 aud 声明中将请求的 URI 设置为受众。如果请求的资源是用户池资源服务器,则资源服务器标识符必须采用 URL 格式。您可以为每个身份验证请求请求一个资源。
此功能专属于用户池 OAuth 2.0 授权服务器的托管登录身份验证。您可以从对端点授权中,在隐式和授权码授予中请求资源绑定。来自令牌端点的令牌刷新授予会延续来自原始请求的 aud 声明。它当前在 SDK 身份验证模型中不可用。
对 Amazon Cognito 用户池实施资源绑定
-
在用户池中使用唯一标识符配置一个或多个资源服务器。
-
在向
/oauth2/authorize的授权请求中,请求授权码或隐式授予,并包含resource参数。resource的值必须是 URL 格式的资源服务器标识符或 URL。例如&resource=https://solar-system-data-api.example.com。 -
授权服务器验证资源请求,完成身份验证,并将访问令牌
aud声明设置为请求的资源 URL。 -
为了验证令牌是专门为其发布,使用用户访问令牌的资源会检查
aud声明。