

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

# 使用基于角色的访问控制
<a name="role-based-access-control"></a>

Amazon Cognito 身份池为您的经过身份验证的用户分配一组临时的、权限有限的凭证，以访问您的资源。 AWS 每个用户的权限通过您创建的 [IAM 角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html)进行控制。您可以定义规则，以便基于用户 ID 令牌中的声明为每个用户选择角色。您可以为经过身份验证的用户定义一个默认角色。您也可以为未经身份验证的来宾用户定义一个具有有限权限的单独的 IAM 角色。

## 为角色映射创建角色
<a name="creating-roles-for-role-mapping"></a>

请务必为每个角色添加适当的信任策略，这样只能由 Amazon Cognito 针对您的身份池中经过身份验证的用户担任。下面是此类信任策略的示例：

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Federated": "cognito-identity.amazonaws.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "cognito-identity.amazonaws.com:aud": "us-east-1:12345678-corner-cafe-123456790ab"
        },
        "ForAnyValue:StringLike": {
          "cognito-identity.amazonaws.com:amr": "authenticated"
        }
      }
    }
  ]
}
```

------

此策略允许来自 `cognito-identity.amazonaws.com` (OpenID Connect 令牌的发布者) 的联合身份用户担任该角色。此外，策略限制令牌的 `aud` (在此示例中为身份池 ID) 匹配身份池。最后，策略指定的由 Amazon Cognito `GetOpenIdToken` API 操作发布的令牌的多值 `amr` 声明的数组成员之一具有值 `authenticated`。

## 授予传递角色权限
<a name="granting-pass-role-permission"></a>

要允许用户为角色设置超过该用户在身份池上的现有权限的权限，您需授予用户 `iam:PassRole` 权限以将角色传递给 `set-identity-pool-roles` API。例如，如果用户无法写入 Amazon S3，但用户在身份池上设置的 IAM 角色可向 Amazon S3 授予写入权限，则用户只能在已向该角色授予 `iam:PassRole` 权限的情况下设置该角色。以下示例策略介绍了如何提供 `iam:PassRole` 权限。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "Stmt1",
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:iam::123456789012:role/myS3WriteAccessRole"
            ]
        }
    ]
}
```

------

在此策略示例中，将 `iam:PassRole` 权限授予了角色 `myS3WriteAccessRole`。使用角色的 Amazon Resource Name（ARN）指定该角色。您必须将此策略附加到您的用户。有关更多信息，请参阅[使用管理的策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-using.html)。

**注意**  
Lambda 函数使用基于资源的策略，该策略直接附加至 Lambda 函数本身。创建调用 Lambda 函数的规则时，您未传递角色，因此创建规则的用户无需 `iam:PassRole` 权限。有关 Lambda 函数授权的更多信息，请参阅[管理权限：使用 Lambda 函数策略](https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html#intro-permission-model-access-policy)。

## 使用令牌向用户分配角色
<a name="using-tokens-to-assign-roles-to-users"></a>

对于通过 Amazon Cognito 用户池登录的用户，角色可在用户池分配的 ID 令牌中进行传递。角色将显示在 ID 令牌的以下声明中：
+ `cognito:preferred_role` 声明是角色 ARN。
+ `cognito:roles`声明是一个以逗号分隔的字符串，其中包含一组允许的角色。 ARNs

声明按如下方式设置：
+ `cognito:preferred_role` 声明设置为组中具有最大 (最小) `Precedence` 值的角色。如果只有一个允许的角色，则 `cognito:preferred_role` 设置为该角色。如果存在多个角色且没有一个角色具有最高优先级，则此声明未设置。
+ 如果至少存在一个角色，则 `cognito:roles` 声明已设置。

使用令牌分配角色时，如果存在多个可向用户分配的角色，Amazon Cognito 身份池（联合身份）将按以下方式选择角色：
+ 如果[GetCredentialsForIdentity](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetCredentialsForIdentity.html)`CustomRoleArn`参数已设置并且与`cognito:roles`声明中的角色匹配，则使用该参数。如果此参数与 `cognito:roles` 中的角色不匹配，则拒绝访问。
+ 如果 `cognito:preferred_role` 声明已设置，请使用它。
+ 如果未设置`cognito:preferred_role`声明，则`cognito:roles`声明已设置，`CustomRoleArn`且未在调用中指定`GetCredentialsForIdentity`，则使用控制台中的**角色解析**设置或`AmbiguousRoleResolution`字段（在 [SetIdentityPoolRoles](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_SetIdentityPoolRoles.html)API 的`RoleMappings`参数中）来确定要分配的角色。

## 使用基于规则的映射向用户分配角色
<a name="using-rules-to-assign-roles-to-users"></a>

规则允许您将身份提供商令牌的声明映射到 IAM 角色。

每个规则指定一个令牌声明（例如 Amazon Cognito 用户池的 ID 令牌中的用户属性）、匹配类型、值和 IAM 角色。匹配类型可以是 `Equals`、`NotEqual`、`StartsWith` 或 `Contains`。如果用户拥有声明的匹配值，则该用户可在获取凭证后担任该角色。例如，您可以创建一个规则，为 `custom:dept` 自定义属性值为 `Sales` 的用户分配一个特定的 IAM 角色。

**注意**  
在规则设置中，自定义属性需要使用 `custom:` 前缀，以便将它们与标准属性区分开来。

规则按顺序进行评估，并使用第一条匹配规则的 IAM 角色，除非指定 `CustomRoleArn` 以覆盖顺序。有关 Amazon Cognito 用户池中用户属性的更多信息，请参阅[使用用户属性](user-pool-settings-attributes.md)。

您可以在身份池（联合身份）控制台中为身份验证提供商设置多条规则。按顺序应用规则。您可以拖动规则以更改其顺序。第一条匹配规则优先。如果匹配类型为 `NotEqual` 且声明不存在，则不会对规则进行评估。如果没有规则匹配，则**角色解析**设置应用到**使用经过身份验证的原定设置角色**或**拒绝请求**。

在 API 和 CLI 中，您可以指定在[RoleMapping](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_RoleMapping.html)类型字段中没有匹配规则时要分配的角色，该`AmbiguousRoleResolution`字段在 [SetIdentityPoolRoles](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_SetIdentityPoolRoles.html)API 的`RoleMappings`参数中指定。

要在 Amazon Cognito 控制台中向身份提供者添加基于规则的映射，请添加或更新 IdP，然后选择**角色选择**下面的**使用规则选择角色**。在这里，您可以添加规则，将提供者声明映射到 IAM 角色。

您可以使用类型的`RulesConfiguration`字段在 AWS CLI 或 API 中为身份提供者设置基于规则的[RoleMapping](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_RoleMapping.html)映射。您可以在 [SetIdentityPoolRoles](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_SetIdentityPoolRoles.html)API 的`RoleMappings`参数中指定此字段。

例如，以下 AWS CLI 命令添加了一条规则，该规则将角色分配`arn:aws:iam::123456789012:role/Sacramento_team_S3_admin`给萨克拉曼多所在地经过 OIDC IdP 身份验证的用户：`arn:aws:iam::123456789012:oidc-provider/myOIDCIdP`

```
aws cognito-identity set-identity-pool-roles --region us-east-1 --cli-input-json file://role-mapping.json
```

**`role-mapping.json` 的内容**：

```
{
    "IdentityPoolId": "us-east-1:12345678-corner-cafe-123456790ab",
    "Roles": {
        "authenticated": "arn:aws:iam::123456789012:role/myS3WriteAccessRole",
        "unauthenticated": "arn:aws:iam::123456789012:role/myS3ReadAccessRole"
    },
    "RoleMappings": {
        "arn:aws:iam::123456789012:oidc-provider/myOIDCIdP": {
            "Type": "Rules",
            "AmbiguousRoleResolution": "AuthenticatedRole",
            "RulesConfiguration": {
                "Rules": [
                    {
                        "Claim": "locale",
                        "MatchType": "Equals",
                        "Value": "Sacramento",
                        "RoleARN": "arn:aws:iam::123456789012:role/Sacramento_team_S3_admin"
                    }
                ]
            }
        }
    }
}
```

对于每个用户池或为某个身份池配置的其他身份验证提供商，您可以创建最多 25 条规则。此限制不可调整。有关更多信息，请参阅 [Amazon Cognito 中的配额](https://docs.aws.amazon.com/cognito/latest/developerguide/limits.html)。

## 基于规则的映射中使用的令牌声明
<a name="token-claims-for-role-based-access-control"></a>

**Amazon Cognito**

Amazon Cognito ID 令牌以 JSON Web Token（JWT）表示。令牌包含有关经过身份验证的用户的身份声明，例如 `name`、`family_name` 和 `phone_number`。有关标准声明的更多信息，请参阅 [OpenID Connect 规范](http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims)。除了标准声明之外，以下是特定于 Amazon Cognito 的额外声明：
+ `cognito:groups`
+ `cognito:roles`
+ `cognito:preferred_role`

**Amazon**

以下声明以及这些声明可能的值可与 Login with Amazon 配合使用：
+ `iss`：www.amazon.com
+ `aud`：应用程序 ID
+ `sub`：Login with Amazon 令牌中的 `sub`

**Facebook**

以下声明以及这些声明可能的值可与 Facebook 配合使用：
+ `iss`：graph.facebook.com
+ `aud`：应用程序 ID
+ `sub`：Facebook 令牌中的 `sub`

**Google**

Google 令牌包含 [OpenID Connect 规范](http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims)中的标准声明。OpenID 令牌中的所有声明均可用于基于规则的映射。请参阅 Google 的 [OpenID Connect](https://developers.google.com/identity/protocols/OpenIDConnect) 网站，了解 Google 令牌中包含的声明。

**Apple**

Apple 令牌包含 [OpenID Connect 规范](http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims)中的标准声明。请参阅 Apple 文档中的[使用 Sign in with Apple 对用户进行身份验证](https://developer.apple.com/documentation/signinwithapple/authenticating-users-with-sign-in-with-apple)，详细了解有关 Apple 令牌提供的声明。Apple 的令牌并不总是包含 `email`。

**OpenID**

OpenID 令牌中的所有声明均可用于基于规则的映射。有关标准声明的更多信息，请参阅 [OpenID Connect 规范](http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims)。请参阅您的 OpenID 提供商文档，了解其中包含的任何额外声明。

**SAML**

根据收到的 SAML 断言分析声明。SAML 断言中包含的所有声明均可在基于规则的映射中使用。

## 基于角色的访问控制的最佳实践
<a name="best-practices-for-role-based-access-control"></a>

**重要**  
如果最终用户可修改您映射到角色的声明，则任何最终用户均可担任您的角色并相应地设置策略。仅将无法由最终用户直接设置的声明映射到具有提升的权限的角色。在 Amazon Cognito 用户池中，您可以为每个用户属性设置每个应用程序的读取和写入权限。

**重要**  
如果您在 Amazon Cognito 用户池中为组设置角色，这些角色将通过用户的 ID 令牌进行传递。要使用这些角色，您还必须为身份池中选择的通过身份验证的角色设置 **Choose role from token**（使用令牌选择角色）。  
您可以使用控制台中的**角色解析**设置和 [SetIdentityPoolRoles](https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_SetIdentityPoolRoles.html)API 的`RoleMappings`参数来指定无法通过令牌确定正确的角色时的默认行为。