

# AWS 执行代码逻辑如何评估允许或拒绝访问的请求
<a name="reference_policies_evaluation-logic_policy-eval-denyallow"></a>

AWS 执行代码决定是应该允许还是拒绝发送到 AWS 的请求。AWS 评估适用于请求上下文的所有策略。下面概述了 AWS 策略评估逻辑。
+ 默认情况下，除 AWS 账户根用户 外，所有请求都被隐式否定，具有完全访问权限。
+ 请求必须由遵循以下被允许的评估逻辑的策略或一组策略明确允许。
+ 显式拒绝将会覆盖显式允许。

策略评估可能会有所不同，具体视请求是在单个账户内还是跨账户请求中而定。有关如何针对单一账户中的 IAM 角色或用户作出策略评估决策的详细信息，请参阅[对单个账户内的请求进行策略评估](reference_policies_evaluation-logic_policy-eval-basics.md)。有关如何针对跨账户请求作出策略评估决策的详细信息，请参阅[跨账户策略评估逻辑](reference_policies_evaluation-logic-cross-account.md)。
+ **Deny evaluation**（拒绝评估）- 默认情况下，所有请求都被拒绝。这称为[隐式拒绝](reference_policies_evaluation-logic_AccessPolicyLanguage_Interplay.md)。AWS 执行代码评估账户中应用于请求的所有策略。其中包含 AWS Organizations SCP 和 RCP、基于资源的策略、基于身份的策略、IAM 权限边界和会话策略。在所有这些策略中，执行代码查找应用于请求的 `Deny` 语句。这称为[显式拒绝](reference_policies_evaluation-logic_AccessPolicyLanguage_Interplay.md)。如果执行代码找到一个适用的显式拒绝，则该执行代码将返回 **Deny** 的最终决定。如果没有显式拒绝，则执行代码评估会继续。
+ **AWS Organizations RCP**：执行代码会评估适用于请求的 AWS Organizations 资源控制策略（RCP）。RCP 适用于附加了 RCP 的账户的资源。如果执行代码没有在 RCP 中找到任何适用的 `Allow` 语句，则执行代码将返回 **Deny** 的最终决定。请注意，当启用 RCP 时，系统会自动创建一个名为 `RCPFullAWSAccess` 的 AWS 托管式策略，并将其附加到组织中的每个实体，包括根、每个 OU 和 AWS 账户。`RCPFullAWSAccess` 无法分离，因此始终将有一个 `Allow` 语句。如果没有 RCP，或者 RCP 允许所请求的操作，则执行代码评估继续适用。
+ **AWS Organizations SCP**：执行代码会评估适用于请求的 AWS Organizations 服务控制策略（SCP）。SCP 适用于附加 SCP 的账户的主体。如果执行代码没有在 SCP 中找到任何适用的 `Allow` 语句，则执行代码将返回 **Deny** 的最终决定。如果没有 SCP，或者 SCP 允许所请求的操作，则执行代码评估继续。
+ **基于资源的策略** — 在同一账户中，基于资源的策略会对策略评估产生不同的影响，具体取决于访问资源的主体类型以及基于资源的策略中允许的主体。根据主体的类型，`Allow` 在基于资源的策略中可能会导致最终决定 `Allow`，即使基于身份的策略、权限边界或会话策略中存在隐式拒绝。

  对于大多数资源，您只需要在基于身份的策略或基于资源的策略中明确 `Allow` 主体访问权限。[IAM 角色信任策略](access_policies-cross-account-resource-access.md#access_policies-cross-account-delegating-resource-based-policies)和 [KMS 密钥策略](https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html)是此逻辑的例外，因为它们必须明确允许[主体](reference_policies_elements_principal.md)的访问权限。非 IAM 和 AWS KMS 的基于资源的服务策略也可能要求在同一账户中作出显式 `Allow` 声明，才能授予访问权限。有关详细信息，请参阅您使用的特定服务的文档。

  对于单个账户策略评估请求，当指定的主体是 IAM 用户、IAM 角色或会话主体时，基于资源的策略逻辑会与其他策略类型有所不同。会话主体包括 [IAM 角色会话](reference_policies_elements_principal.md#principal-role-session)或 [AWS STS 联合用户主体](reference_policies_elements_principal.md#sts-session-principals)。如果基于资源的策略直接向提出请求的 IAM 用户或会话主体授予权限，则基于身份的策略、权限边界或会话策略中的隐式拒绝不会影响最终决策。
  + **IAM 角色** — 授予 IAM 角色 ARN 权限的基于资源的策略受权限边界或会话策略中隐式拒绝的限制。可以在 Principal 元素或 `aws:PrincipalArn` 条件键中指定角色 ARN。在这两种情况下，提出请求的主体都是 **IAM 角色会话**。

    权限边界和会话策略不限制在 Principal 元素中使用带通配符 (\$1) 的 `aws:PrincipalArn` 条件键授予权限，除非基于身份的策略包含显式拒绝。有关更多信息，请参阅 [IAM 角色主体](reference_policies_elements_principal.md#principal-roles)。

    **角色示例 ARN**

    ```
    arn:aws:iam::111122223333:role/examplerole
    ```
  + **IAM 角色会话**— 在同一账户中，向 IAM 角色会话 ARN 授予权限的基于资源的策略直接向担任的角色会话授予权限。直接授予会话的权限不受基于身份的策略、权限边界或会话策略中的隐式拒绝的限制。当您担任角色并提出请求时，发出请求的主体是 IAM 角色会话 ARN，而不是角色本身的 ARN。有关更多信息，请参阅 [角色会话主体](reference_policies_elements_principal.md#principal-role-session)。

    **示例角色会话 ARN**

    ```
    arn:aws:sts::111122223333:assumed-role/examplerole/examplerolesessionname
    ```
  + **IAM 用户** – 在同一账户中，向 IAM 用户 ARN（不是联合身份用户会话）授予权限的基于资源的策略不受基于身份的策略或权限边界中隐式拒绝的限制。

    **示例 IAM 用户 ARN**

    ```
    arn:aws:iam::111122223333:user/exampleuser
    ```
  + **AWS STS 联合用户主体** – 联合用户会话是通过调用 [`GetFederationToken`](id_credentials_temp_request.md#api_getfederationtoken) 创建的会话。当联合身份用户发出请求时，发出请求的主体是联合身份用户 ARN，而不是联合身份的 IAM 用户的 ARN。在同一个账户中，将权限授予联合身份用户 ARN 的基于资源的策略直接将权限授予会话。直接授予会话的权限不受基于身份的策略、权限边界或会话策略中的隐式拒绝的限制。

    但是，如果基于资源的策略向联合身份的 IAM 用户的 ARN 授予权限，则联合身份用户在会话期间发出的请求将受权限边界或会话策略中隐式拒绝的限制。

    **示例联合用户会话 ARN**

    ```
    arn:aws:sts::111122223333:federated-user/exampleuser
    ```
+ **基于身份的策略**：执行代码会检查主体的基于身份的策略。对于 IAM 用户，这包括用户策略和来自用户所属组的策略。如果没有基于身份的策略或者基于身份的策略中没有允许请求动作的语句，那么请求被隐式否定，执行代码返回 **Deny** 的最终决定。如果任何适用的基于身份的策略中的任何语句都允许请求的动作，则代码评估继续适用。
+ **IAM 权限边界**：执行代码会检查主体使用的 IAM 实体是否具有权限边界。如果用于设置权限边界的策略不允许所请求的操作，则请求会被隐式拒绝。执行代码将返回**拒绝**最终决定。如果没有权限边界，或者权限边界允许所请求的操作，则代码评估继续适用。
+ **会话策略**：执行代码检查主体是否为会话主体。会话主体包括 IAM 角色会话或者 AWS STS 联合用户会话。如果主体不是会话主体，执行代码将返回 **Allow** 的最终决定。

  对于会话主体，执行代码检查请求中是否传递了会话策略。您可以传递会话策略，同时使用 AWS CLI 或 AWS API 为某个角色或 AWS STS 联合用户主体获取临时凭证。如果您没有传递会话策略，则会创建默认会话策略，执行代码返回 **Allow** 的最终决定。
  + 如果会话策略存在但不允许所请求的操作，则请求会被隐式拒绝。执行代码将返回**拒绝**最终决定。
  + 执行代码将检查主体是否为角色会话。如果主体是角色会话，那么请求是**已允许**。否则，请求被隐式拒绝，执行代码返回 **Deny** 的最终决定。
  + 如果会话策略在场并允许请求的动作，那么执行代码返回一个 **Allow** 的最终决策。

# 对单个账户内的请求进行策略评估
<a name="reference_policies_evaluation-logic_policy-eval-basics"></a>

## 对 IAM 角色进行策略评估
<a name="policy-eval-basics-single-account-role"></a>

以下流程图详细介绍了如何针对单一账户中的 IAM 角色作出策略评估决策。

![\[单个账户中 IAM 角色的评估流程图\]](http://docs.aws.amazon.com/zh_cn/IAM/latest/UserGuide/images/PolicyEvaluationSingleAccountRole.png)


## 对 IAM 用户进行策略评估
<a name="policy-eval-basics-single-account-user"></a>

以下流程图详细介绍了如何针对单一账户中的 IAM 用户作出策略评估决策。

![\[单个账户中 IAM 用户的评估流程图\]](http://docs.aws.amazon.com/zh_cn/IAM/latest/UserGuide/images/PolicyevaluationSingleAccountUser.png)


## 基于身份的策略和基于资源的策略评估示例
<a name="reference_policies_evaluation-logic_policies_evaluation_example"></a>

策略的最常见类型是基于身份的策略和基于资源的策略。当请求访问资源时，AWS 会评估策略为同一账户中**至少一个允许**所授予的所有权限。任一项策略中的显式拒绝将覆盖允许。

**重要**  
如果同一账户中基于身份的策略或基于资源的策略其中一个允许该请求，而另一个不允许，仍可允许该请求。

假定 Carlos 具有用户名 `carlossalazar`，他尝试将文件保存到 `amzn-s3-demo-bucket-carlossalazar-logs` Amazon S3 存储桶。

还假定将以下策略附加到 `carlossalazar` IAM 用户。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AllowS3ListRead",
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:GetAccountPublicAccessBlock",
                "s3:ListAccessPoints",
                "s3:ListAllMyBuckets"
            ],
            "Resource": "arn:aws:s3:::*"
        },
        {
            "Sid": "AllowS3Self",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::amzn-s3-demo-bucket-carlossalazar/*",
                "arn:aws:s3:::amzn-s3-demo-bucket-carlossalazar"
            ]
        },
        {
            "Sid": "DenyS3Logs",
            "Effect": "Deny",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::*log*"
        }
    ]
}
```

------

此策略中的 `AllowS3ListRead` 语句允许 Carlos 查看账户中的所有存储桶的列表。`AllowS3Self` 语句允许 Carlos 完全访问与其用户名同名的存储桶。`DenyS3Logs` 语句拒绝 Carlos 访问名称中包含 `log` 的任何 S3 存储桶。

此外，以下基于资源的策略（称为存储桶策略）附加到 `amzn-s3-demo-bucket-carlossalazar` 存储桶。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:user/carlossalazar"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::amzn-s3-demo-bucket-carlossalazar/*",
                "arn:aws:s3:::amzn-s3-demo-bucket-carlossalazar"
            ]
        }
    ]
}
```

------

此策略指定只有 `carlossalazar` 用户可以访问 `amzn-s3-demo-bucket-carlossalazar` 存储桶。

当 Carlos 请求将文件保存到 `amzn-s3-demo-bucket-carlossalazar-logs` 存储桶时，AWS 将确定应用于请求的策略。在此示例中，仅基于身份的策略和基于资源的策略适用。这些都是权限策略。由于没有任何权限边界适用，评估逻辑将减少为以下逻辑。

![\[评估流程图\]](http://docs.aws.amazon.com/zh_cn/IAM/latest/UserGuide/images/EffectivePermissionsShort.png)


AWS 首先检查应用于请求上下文的 `Deny` 语句。它找到一个，因为基于身份的策略显式拒绝 Carlos 访问用于日志记录的任何 S3 存储桶。拒绝 Carlos 访问。

假设他随后意识到自己的错误，尝试将文件保存到 `amzn-s3-demo-bucket-carlossalazar` 存储桶。AWS 检查 `Deny` 语句，但未找到。然后，它检查权限策略。基于身份的策略和基于资源的策略均允许请求。因此，AWS 允许请求。如果其中任何一个显式拒绝了语句，则将拒绝请求。如果其中一种策略类型允许请求，而另一种不允许，则仍允许请求。

# 跨账户策略评估逻辑
<a name="reference_policies_evaluation-logic-cross-account"></a>

您可以允许一个账户中的主体访问另一个账户中的资源。这称为 cross-account access（跨账户存取）。当您允许跨账户访问时，主体所在的账户称为*受信任* 账户。资源所在的账户是*信任* 账户。

要允许跨账户访问，请将基于资源的策略附加到您要共享的资源。您还必须向在请求中充当主体的身份附加基于身份的策略。信任账户中基于资源的策略必须指定受信任账户中有权访问资源的主体。您可以指定整个账户或其 IAM 用户、AWS STS 联合用户主体、IAM 角色或代入角色会话。您还可以将 AWS 服务指定为主体。有关更多信息，请参阅 [如何指定主体](reference_policies_elements_principal.md#Principal_specifying)。

主体的基于身份的策略必须允许对信任服务中的资源进行请求的访问。您可以通过指定资源的 ARN 来执行此操作。

在 IAM 中，您可以将基于资源的策略附加到 IAM 角色，以允许其他账户中的主体代入该角色。角色的基于资源的策略称为角色信任策略。代入该角色之后，允许的主体可以使用生成的临时凭证访问您账户中的多个资源。此访问权限在角色的基于身份的权限策略中定义。如需了解使用角色允许跨账户访问与使用其他基于资源的策略允许跨账户访问之间的不同之处，请参阅[IAM 中的跨账户资源访问](access_policies-cross-account-resource-access.md)。

**重要**  
其他服务可能会影响策略评估逻辑。例如，AWS Organizations 支持可应用于一个或多个账户中的主体和资源的[服务控制策略](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps.html)和[资源控制策略](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_rcps.html)。AWS Resource Access Manager 支持[策略片段](https://docs.aws.amazon.com/ram/latest/userguide/permissions.html)，用于控制允许主体对与其共享的资源执行哪些操作。

## 确定是否允许跨账户请求
<a name="policy-eval-cross-account"></a>

对于跨账户请求，受信任账户 `AccountA` 中的请求者必须具有基于身份的策略。该策略必须允许他们向信任账户 `AccountB` 中的资源发出请求。此外，`AccountB` 中的基于资源的策略必须允许 `AccountA` 中的请求者访问资源。

当您发出跨账户请求时，AWS 会执行两个评估。AWS 评估信任账户和受信任账户中的请求。有关如何在单个账户中评估请求的更多信息，请参阅[AWS 执行代码逻辑如何评估允许或拒绝访问的请求](reference_policies_evaluation-logic_policy-eval-denyallow.md)。仅当两个评估都返回 `Allow` 决策时，才允许该请求。

![\[跨账户 评估\]](http://docs.aws.amazon.com/zh_cn/IAM/latest/UserGuide/images/policy_cross-account-eval-simple.png)


1. 当一个账户中的主体发出请求以访问另一个账户中的资源时，这是一个跨账户请求。

1. 请求主体存在于受信任账户 (`AccountA`) 中。当 AWS 评估此账户时，它会检查基于身份的策略以及可以限制基于身份的策略的任何策略。有关更多信息，请参阅 [评估具有权限边界的基于身份的策略](reference_policies_evaluation-logic.md#policy-eval-basics-id-bound)。

1. 请求的资源存在于信任账户 (`AccountB`) 中。当 AWS 评估此账户时，它会检查附加到所请求资源的基于资源的策略，以及可以限制基于资源的策略的任何策略。有关更多信息，请参阅 [评估基于身份的策略以及基于资源的策略](reference_policies_evaluation-logic.md#policy-eval-basics-id-rdp)。

1. 仅当两个账户策略评估均允许该请求时，AWS 才允许该请求。

以下流程图详细介绍了如何针对跨账户请求作出策略评估决策。同样，仅当两个账户策略评估均允许该请求时，AWS 才会允许该请求。

![\[详细的跨账户策略评估\]](http://docs.aws.amazon.com/zh_cn/IAM/latest/UserGuide/images/PolicyEvaluationCrossAccount.png)


## 跨账户策略评估示例
<a name="policies_evaluation_example-cross-account"></a>

以下示例演示了一个账户中基于资源的策略向另一个账户中的角色授予权限的情况。

假设 Carlos 是一名开发人员，在账户 111111111111 中具有名为 `Demo` 的 IAM 角色。他想要将文件保存到账户 222222222222 中的 `amzn-s3-demo-bucket-production-logs` Amazon S3 存储桶。

还假定将以下策略附加到 `Demo` IAM 角色。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AllowS3ListRead",
            "Effect": "Allow",
            "Action": "s3:ListAllMyBuckets",
            "Resource": "*"
        },
        {
            "Sid": "AllowS3ProductionObjectActions",
            "Effect": "Allow",
            "Action": "s3:*Object*",
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket-production/*"
        },
        {
            "Sid": "DenyS3Logs",
            "Effect": "Deny",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::*log*",
                "arn:aws:s3:::*log*/*"
            ]
        }
    ]
}
```

------

此策略中的 `AllowS3ListRead` 语句允许 Carlos 查看 Amazon S3 中所有存储桶的列表。`AllowS3ProductionObjectActions` 语句允许 Carlos 对 `amzn-s3-demo-bucket-production` 存储桶中对象的完全访问权限。

此外，以下基于资源的策略（称为存储桶策略）附加到账户 222222222222 中的 `amzn-s3-demo-bucket-production` 存储桶。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject*",
                "s3:PutObject*",
                "s3:ReplicateObject",
                "s3:RestoreObject"
            ],
            "Principal": { "AWS": "arn:aws:iam::111111111111:role/Demo" },
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket-production/*"
        }
    ]
}
```

------

此策略允许 `Demo` 角色访问 `amzn-s3-demo-bucket-production` 存储桶中的对象。该角色以创建和编辑存储桶中的对象，但不能删除。该角色无法管理存储桶本身。

当 Carlos 请求将文件保存到 `amzn-s3-demo-bucket-production-logs` 存储桶时，AWS 将确定应用于请求的策略。在这种情况下，附加到 `Demo` 角色的基于身份的策略是在账户 `111111111111` 中应用的唯一策略。在账户 `222222222222` 中，`amzn-s3-demo-bucket-production-logs` 存储桶没有附加基于资源的策略。AWS 评估账户 `111111111111` 时返回了决策 `Deny`。这是因为基于身份的策略中的 `DenyS3Logs` 语句明确拒绝访问任何日志存储桶。有关如何在单个账户中评估请求的更多信息，请参阅[AWS 执行代码逻辑如何评估允许或拒绝访问的请求](reference_policies_evaluation-logic_policy-eval-denyallow.md)。

由于在一个账户中明确拒绝了请求，因此最终决策是拒绝请求。

![\[向 amzn-s3-demo-bucket-production-logs 存储桶发出请求\]](http://docs.aws.amazon.com/zh_cn/IAM/latest/UserGuide/images/policy_cross-account-eval-example.png)


假设随后 Carlos 意识到他的错误并尝试将文件保存到 `Production` 存储桶。AWS 首先检查账户 `111111111111` 以确定是否允许请求。仅基于身份的策略适用并允许请求。随后，AWS 检查账户 `222222222222`。仅附加到 `Production` 存储桶的基于资源的策略适用，并允许请求。由于两个账户均允许请求，因此最终决策是允许请求。

![\[对 Production 存储桶的请求\]](http://docs.aws.amazon.com/zh_cn/IAM/latest/UserGuide/images/policy_cross-account-eval-example-correct.png)
