

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

# 使用 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 证书的标记会话。 | 