

# 示例 4：存储桶拥有者针对自己未拥有的对象授予跨账户权限
<a name="example-walkthroughs-managing-access-example4"></a>

**Topics**
+ [了解跨账户权限和使用 IAM 角色](#access-policies-walkthrough-example4-overview)
+ [步骤 0：准备演练](#access-policies-walkthrough-example4-step0)
+ [步骤 1：执行账户 A 任务](#access-policies-walkthrough-example4-step1)
+ [步骤 2：执行账户 B 任务](#access-policies-walkthrough-example4-step2)
+ [步骤 3：执行账户 C 任务](#access-policies-walkthrough-example4-step3)
+ [步骤 4：清除](#access-policies-walkthrough-example4-step6)
+ [相关资源](#RelatedResources-managing-access-example4)

 在此示例场景中，您拥有一个存储桶，并且启用了其他 AWS 账户以上传对象。如果您已经为存储桶的 S3 对象所有权应用了强制存储桶拥有者设置，那么您将拥有存储桶中的所有对象，包括另一个 AWS 账户 所编写的对象。此方法将解决存储桶拥有者未拥有对象的问题。然后，您可以将权限委派给自己账户中的用户或其他 AWS 账户。假设尚未启用 S3 对象所有权的强制存储桶拥有者设置。也就是说，您的存储桶中可以有其他 AWS 账户所拥有的对象。

现在，假设作为存储桶拥有者，您需要向另一个账户中的用户授予对象（无论拥有者是谁）的跨账户权限。例如，该用户可以是需要访问对象元数据的账单应用程序。存在两个核心问题：
+ 存储桶拥有者对其他 AWS 账户创建的对象不拥有权限。因此，存储桶拥有者若要针对自己未拥有的对象授予权限，必须先由对象拥有者向存储桶拥有者授予权限。对象拥有者是创建对象版本的 AWS 账户。然后，存储桶拥有者才能委托这些权限。
+ 存储桶拥有者账户可以向其账户中的用户委派权限（请参阅[示例 3：存储桶拥有者授予不属于自己的对象的权限](example-walkthroughs-managing-access-example3.md)）。但是，存储桶拥有者账户无法将权限委派给其它 AWS 账户，因为不支持跨账户委派。

在这种情况下，存储桶拥有者可以创建具有对象访问权限的 AWS Identity and Access Management（IAM）角色，然后存储桶拥有者可以向另一个 AWS 账户授予临时担任该角色的权限，使它可以访问存储桶中的对象。

**注意**  
S3 对象所有权是 Amazon S3 存储桶级别的设置，您可以使用该设置来控制上传到存储桶的对象的所有权和禁用或启用 ACL。默认情况下，对象所有权设为强制存储桶拥有者设置，并且所有 ACL 均处于禁用状态。禁用 ACL 后，存储桶拥有者拥有存储桶中的所有对象，并使用访问管理策略来专门管理对这些对象的访问权限。  
 Amazon S3 中的大多数现代使用案例不再需要使用 ACL。我们建议您将 ACL 保持为禁用状态，除非有需要单独控制每个对象的访问权限的情况。禁用 ACL 后，您可以使用策略来控制对存储桶中所有对象的访问权限，无论是谁将对象上传到您的存储桶。有关更多信息，请参阅 [为您的存储桶控制对象所有权和禁用 ACL。](about-object-ownership.md)。

## 了解跨账户权限和使用 IAM 角色
<a name="access-policies-walkthrough-example4-overview"></a>

 IAM 角色可实现多种资源委托访问权限方案，跨账户访问是重要方案之一。在此示例中，存储桶拥有者（账户 A）使用一个 IAM 角色临时将跨账户对象访问权限委派给另一个 AWS 账户（账户 C）中的用户。您创建的每个 IAM 角色都附加了以下两个策略：
+ 一个信任策略，用于标识可以担任角色的其他 AWS 账户。
+ 一个访问策略，用于定义在某个用户担任角色时允许的权限，例如 `s3:GetObject`。有关可以在策略中指定的权限的列表，请参阅 [Amazon S3 的策略操作](security_iam_service-with-iam.md#security_iam_service-with-iam-id-based-policies-actions)。

然后，信任策略中标识的 AWS 账户向其用户授予担任角色的权限。该用户即可执行以下操作以访问对象：
+ 担任角色，然后在响应中获取临时安全凭证。
+ 使用临时安全凭证访问存储桶中的对象。

有关 IAM 角色的更多信息，请参阅《IAM 用户指南》**中的 [IAM 角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html)。

下面概括介绍演练步骤：

![\[使用 IAM 角色的跨账户权限。\]](http://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/images/access-policy-ex4.png)


1. 账户 A 管理员用户附加一个存储桶策略，向账户 B 授予上传对象的条件权限。

1. 账户 A 管理员创建一个 IAM 角色，与账户 C 建立信任，以便该账户中的用户可以访问账户 A。附加到该角色的访问策略限制账户 C 中的用户访问账户 A 时可以执行的操作。

1. 账户 B 管理员将一个对象上传到账户 A 拥有的存储桶，从而向存储桶拥有者授予完全控制权限。

1. 账户 C 管理员创建一个用户，附加一个用户策略允许该用户担任该角色。

1. 账户 C 中的用户首先担任角色，这会向该用户返回临时安全凭证。该用户随后使用这些临时凭证访问存储桶中的对象。

对于此示例，您需要三个账户。下表显示我们如何引用这些账户和这些账户中的管理员用户。根据 IAM 准则（请参阅[关于使用管理员用户来创建资源和授予权限](example-walkthroughs-managing-access.md#about-using-root-credentials)），我们在本演练中并不使用 AWS 账户根用户 凭证。而是在每个账户中创建一个管理员用户，并在创建资源和向他们授予权限时使用这些凭证。


| AWS 账户 ID | 账户名称 | 账户中的管理员用户  | 
| --- | --- | --- | 
|  *1111-1111-1111*  |  账户 A  |  AccountAadmin  | 
|  *2222-2222-2222*  |  账户 B  |  AccountBadmin  | 
|  *3333-3333-3333*  |  账户 C  |  AccountCadmin  | 



## 步骤 0：准备演练
<a name="access-policies-walkthrough-example4-step0"></a>

**注意**  
在演练这些步骤时，您可能需要打开文本编辑器，记下某些信息。具体而言，您需要账户 ID、规范用户 ID、供每个账户连接到控制台的 IAM 用户登录 URL，以及 IAM 用户和角色的 Amazon 资源名称（ARN）。

1. 确保您有三个 AWS 账户并且每个账户都有一个管理员用户，如前面部分的表中所示。

   1. 根据需要注册 AWS 账户。我们将这些账户称为账户 A、账户 B 和账户 C。

   1. 使用账户 A 凭证登录 [IAM 控制台](https://console.aws.amazon.com/iam/home?#home)，然后执行以下操作以创建管理员用户：
      + 创建用户 **AccountAadmin** 并记下其安全凭证。有关添加用户的更多信息，请参阅 *IAM 用户指南*中的[在您的 AWS 账户中创建 IAM 用户](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html)。
      + 通过附加一个授予完全访问权限的用户策略来向 **AccountAadmin** 授予管理员权限。有关说明，请参阅* IAM 用户指南*中的[管理 IAM 策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage.html)。
      + 在 IAM 控制台的**控制面板**中，记下 **IAM 用户登录 URL**。此账户中的用户必须在登录 AWS 管理控制台 时使用此 URL。有关更多信息，请参阅《IAM 用户指南》**中的 [Sign in to the AWS 管理控制台 as an IAM user](https://docs.aws.amazon.com/IAM/latest/UserGuide/getting-started_how-users-sign-in.html)。

   1. 重复上述步骤，在账户 B 和账户 C 中创建管理员用户。

1. 对于账户 C，请记下规范用户 ID。

   在账户 A 中创建 IAM 角色时，信任策略通过指定账户 ID 向账户 C 授予担任该角色的权限。您可以查找账户信息，如下所示：

   1. 使用 AWS 账户 ID 或账户别名、您的 IAM 用户名和密码登录 [Amazon S3 控制台](https://console.aws.amazon.com/s3/)。

   1. 请选择 Amazon S3 存储桶的名称以查看有关该存储桶的详细信息。

   1. 请选择 **Permissions (权限)** 选项卡，然后选择 **Access Control List (访问控制列表)**。

   1. 在 **Access for your AWS 账户 (您的 Amazon 账户的访问权限)** 部分，**Account (账户)** 列中是长标识符，例如 `c1daexampleaaf850ea79cf0430f33d72579fd1611c97f7ded193374c0b163b6`。这是您的规范用户 ID。

1. 创建存储桶策略时，您需要以下信息。记下以下值：
   + **账户 A 的规范用户 ID** – 账户 A 管理员向账户 B 管理员授予条件上传对象权限时，条件指定必须获取对象完全控制权的账户 A 用户的规范用户 ID。
**注意**  
规范用户 ID 是 Amazon S3 独有的概念。它是 64 字符模糊版本的账户 ID。
   + **账户 B 管理员的用户 ARN**：您可以在 [IAM 控制台](https://console.aws.amazon.com/iam/)中找到用户 ARN。您必须选择该用户并在**摘要**选项卡中找到该用户的 ARN。

     在存储桶策略中，向 `AccountBadmin` 授予上传对象的权限，使用 ARN 指定用户。下面是一个示例 ARN 值：

     ```
     arn:aws:iam::AccountB-ID:user/AccountBadmin
     ```

1. 设置 AWS Command Line Interface (CLI) 或 AWS Tools for Windows PowerShell。请务必保存管理员用户凭证，如下所示：
   + 如果使用 AWS CLI，请在配置文件中创建配置文件：`AccountAadmin` 和 `AccountBadmin`。
   + 如果使用 AWS Tools for Windows PowerShell，请确保将用于会话的凭证存储为 `AccountAadmin` 和 `AccountBadmin`。

   有关说明，请参阅 [设置用于演练的工具](policy-eval-walkthrough-download-awscli.md)。

## 步骤 1：执行账户 A 任务
<a name="access-policies-walkthrough-example4-step1"></a>

在此示例中，账户 A 是存储桶拥有者。因此，账户 A 中的用户 AccountAadmin 将执行以下操作：
+ 创建存储桶。
+ 附加存储桶策略，向账户 B 管理员授予上传对象的权限。
+ 创建 IAM 角色，授予账户 C 代入该角色的权限，使其能够访问存储桶中的对象。

### 步骤 1.1：登录到 AWS 管理控制台
<a name="access-policies-walkthrough-cross-account-permissions-acctA-tasks-sign-in-example4"></a>

首先使用账户 A 的 IAM 用户登录 URL，以 **AccountAadmin** 用户身份登录 AWS 管理控制台。此用户将创建一个存储桶并向其附加一个策略。

### 步骤 1.2：创建存储桶并附加存储桶策略
<a name="access-policies-walkthrough-example2d-step1-1"></a>

在 Amazon S3 控制台中，执行以下操作：

1. 创建存储桶。此练习假设存储桶名称是 `amzn-s3-demo-bucket1`。

   有关说明，请参阅 [创建通用存储桶](create-bucket-overview.md)。

1. 附加以下存储桶策略。该策略向账户 B 管理员授予上传对象的条件权限。

   请通过为 `amzn-s3-demo-bucket1`、`AccountB-ID` 和 `CanonicalUserId-of-AWSaccountA-BucketOwner` 提供自己的值来更新策略。

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "111",
               "Effect": "Allow",
               "Principal": {
                   "AWS": "arn:aws:iam::111122223333:user/AccountBadmin"
               },
               "Action": "s3:PutObject",
               "Resource": "arn:aws:s3:::amzn-s3-demo-bucket1/*"
           },
           {
               "Sid": "112",
               "Effect": "Deny",
               "Principal": {
                   "AWS": "arn:aws:iam::111122223333:user/AccountBadmin"
               },
               "Action": "s3:PutObject",
               "Resource": "arn:aws:s3:::amzn-s3-demo-bucket1/*",
               "Condition": {
                   "StringNotEquals": {
                       "s3:x-amz-grant-full-control": "id=CanonicalUserId-of-AWSaccountA-BucketOwner"
                   }
               }
           }
       ]
   }
   ```

------

### 步骤 1.3：在账户 A 中创建一个 IAM 角色以允许账户 C 进行跨账户访问
<a name="access-policies-walkthrough-example2d-step1-2"></a>

在 [IAM 控制台](https://console.aws.amazon.com/iam/)中创建一个 IAM 角色（**examplerole**），授予账户 C 担任该角色的权限。请务必仍以账户 A 管理员身份登录，因为该角色必须在账户 A 中创建。

1. 创建角色之前，准备好定义角色所需权限的托管策略。您可在以后的步骤中将此策略附加到角色。

   1. 在左侧导航窗格中，请选择**策略**，然后选择**创建策略**。

   1. 在 **Create Your Own Policy** 旁，选择 **Select**。

   1. 在 **Policy Name (策略名称)** 字段中输入 **access-accountA-bucket**。

   1. 复制下面的访问策略，然后将其粘贴到 **Policy Document (策略文档)** 字段中。该访问策略授予该角色 `s3:GetObject` 权限，这样，账户 C 用户在担任该角色时只能执行 `s3:GetObject` 操作。

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

****  

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket1/*"
          }
        ]
      }
      ```

------

   1. 选择**创建策略**。

      新策略会显示在托管策略列表中。

1. 在左侧的导航窗格中，选择**角色**，然后选择**创建角色**。

1. 在**选择角色类型**下，选择**用于跨账户访问的角色**，然后单击**提供在您的 AWS 账户之间进行相互访问的权限**旁边的**选择**按钮。

1. 输入账户 C 的账户 ID。

   对于此演练，您不必要求用户经过多重身份验证（MFA）来承担角色，因此请不要选择该选项。

1. 选择**下一步**，设置与该角色关联的权限。

1. 

   选中您创建的 **access-accountA-bucket** 策略旁边的复选框，然后选择**下一步**。

   “Review (审核)”页面随即出现，使您可以在创建角色之前确认其设置。此页面上有一项极为重要，需要注意，即您可发送给需要使用此角色的用户的链接。使用该链接的用户会直接转到已填写“账户 ID”和“角色名称 ”字段的**切换角色**页面。稍后您可以在任何跨账户角色的**角色摘要**页面上看到此链接。

1. 输入 `examplerole` 作为角色名称，然后单击**下一步**。

1. 检查角色后，选择**创建角色**。

   `examplerole` 角色显示在角色列表中。

1. 选择角色名称 `examplerole`。

1. 选择 **Trust Relationships (信任关系)** 选项卡。

1. 选择**显示策略文档**并验证所示信任策略是否与以下策略相符。

   以下信任策略通过允许账户 C 执行 `sts:AssumeRole` 操作，与它建立信任。有关更多信息，请参阅《AWS Security Token Service API Reference》**中的 [https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html)。

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "",
               "Effect": "Allow",
               "Principal": {
                   "AWS": "arn:aws:iam::111122223333:root"
               },
               "Action": "sts:AssumeRole"
           }
       ]
   }
   ```

------

1. 记下您创建的 `examplerole` 角色的 Amazon 资源名称（ARN）。

   稍后在以下步骤中，您附加一个用户策略以允许 IAM 用户担任此角色，并通过 ARN 值标识角色。

## 步骤 2：执行账户 B 任务
<a name="access-policies-walkthrough-example4-step2"></a>

账户 A 拥有的示例存储桶需要由其它账户拥有的对象。在此步骤中，账户 B 管理员使用命令行工具上传对象。
+ 使用 `put-object` AWS CLI 命令，将对象上传到 `amzn-s3-demo-bucket1`。

  ```
  aws s3api put-object --bucket amzn-s3-demo-bucket1 --key HappyFace.jpg --body HappyFace.jpg --grant-full-control id="canonicalUserId-ofTheBucketOwner" --profile AccountBadmin
  ```

  请注意以下几点：
  + `--Profile` 参数指定 `AccountBadmin` 配置文件，因此该对象由账户 B 拥有。
  + 参数 `grant-full-control` 根据存储桶策略的要求向存储桶拥有者授予对象的完全控制权限。
  + `--body` 参数标识要上传的源文件。例如，如果该文件在 Windows 计算机上的 C: 驱动器中，您应指定 `c:\HappyFace.jpg`。

## 步骤 3：执行账户 C 任务
<a name="access-policies-walkthrough-example4-step3"></a>

在前面的步骤中，账户 A 已创建一个角色 `examplerole`，与账户 C 建立了信任。该角色使账户 C 中的用户可以访问账户 A。在此步骤中，账户 C 管理员创建一个用户（Dave），向他委派从账户 A 收到的 `sts:AssumeRole` 权限。此方法让 Dave 可以担任 `examplerole` 并临时获取对账户 A 的访问权限。账户 A 附加到该角色的访问策略将限制 Dave 在访问账户 A 时可以执行的操作，具体而言，就是获取 `amzn-s3-demo-bucket1` 中的对象。

### 步骤 3.1：在账户 C 中创建一个用户并向其委派担任 examplerole 的权限
<a name="cross-acct-access-using-role-step3-1"></a>

1. 首先使用账户 C 的 IAM 用户登录 URL，以 **AccountCadmin** 用户身份登录 AWS 管理控制台。

   

1. 在 [IAM 控制台](https://console.aws.amazon.com/iam/)中，创建用户 Dave。

   有关分步说明，请参阅《IAM 用户指南》**中的[创建 IAM 用户（AWS 管理控制台）](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html#id_users_create_console)。

1. 记下 Dave 的凭证。Dave 需要这些凭证才能担任 `examplerole` 角色。

1. 为 IAM 用户 Dave 创建一个内联策略，向 Dave 委派担任账户 A 中的 `examplerole` 角色的 `sts:AssumeRole` 权限。

   1. 在左侧导航窗格中，请选择**用户**。

   1. 请选择用户名 **Dave**。

   1. 在用户详细信息页面上，选择 **Permissions (权限)** 选项卡，然后展开 **Inline Policies (内联策略)** 部分。

   1. 请选择 **click here (单击此处)** (或 **Create User Policy (创建用户策略)**)。

   1. 选择 **Custom Policy**，然后选择 **Select**。

   1. 在 **Policy Name (策略名称)** 字段中为策略输入一个名称。

   1. 将以下策略复制到 **Policy Document (策略文档)** 字段中。

      您必须提供 `AccountA-ID` 来更新策略。

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

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "sts:AssumeRole"
                  ],
                  "Resource": "arn:aws:iam::111122223333:role/examplerole"
              }
          ]
      }
      ```

------

   1. 选择**应用策略**。

1. 通过添加另一个配置文件 `AccountCDave` 将 Dave 的凭证保存到 AWS CLI 的配置文件。

   ```
   [profile AccountCDave]
   aws_access_key_id = UserDaveAccessKeyID
   aws_secret_access_key = UserDaveSecretAccessKey
   region = us-west-2
   ```

### 步骤 3.2：担任角色（examplerole）并访问对象
<a name="cross-acct-access-using-role-step3-2"></a>

现在 Dave 可以访问账户 A 拥有的存储桶中的对象，如下所示：
+ Dave 首先使用自己的凭证担任 `examplerole`。这会返回临时凭证。
+ Dave 随后使用临时凭证访问账户 A 的存储桶中的对象。

1. 在命令提示符处，使用 `AccountCDave` 配置文件运行下面的 AWS CLI `assume-role` 命令。

   您必须通过提供 `AccountA-ID`（其中定义了 `examplerole`）在命令中更新 ARN 值。

   ```
   aws sts assume-role --role-arn arn:aws:iam::AccountA-ID:role/examplerole --profile AccountCDave --role-session-name test
   ```

   在响应中，AWS Security Token Service（AWS STS）返回临时安全凭证（访问密钥 ID、秘密访问密钥和会话令牌）。

1. 将临时安全凭证保存在 AWS CLI 配置文件中的 `TempCred` 配置文件下。

   ```
   [profile TempCred]
   aws_access_key_id = temp-access-key-ID
   aws_secret_access_key = temp-secret-access-key
   aws_session_token = session-token
   region = us-west-2
   ```

1. 在命令提示符处，使用临时凭证运行以下 AWS CLI 命令以访问对象。例如，该命令指定 head-object API 以检索 `HappyFace.jpg` 对象的对象元数据。

   ```
   aws s3api get-object --bucket amzn-s3-demo-bucket1 --key HappyFace.jpg SaveFileAs.jpg --profile TempCred
   ```

   因为附加到 `examplerole` 的访问策略允许执行这些操作，所以 Amazon S3 会处理请求。您可以对存储桶中的任何其他对象尝试任何其他操作。

   如果您尝试任何其它操作（例如 `get-object-acl`），则系统会拒绝权限，因为不允许角色执行该操作。

   ```
   aws s3api get-object-acl --bucket amzn-s3-demo-bucket1 --key HappyFace.jpg --profile TempCred
   ```

   我们使用用户 Dave 担任角色，并使用临时凭证访问对象。它还可以是账户 C 中访问 `amzn-s3-demo-bucket1` 中的对象的应用程序。应用程序可以获取临时安全凭证，账户 C 可以向应用程序委托担任 `examplerole` 的权限。

## 步骤 4：清除
<a name="access-policies-walkthrough-example4-step6"></a>

1. 完成测试之后，您可以执行以下操作来进行清理：

   1. 使用账户 A 凭证登录 [AWS 管理控制台](https://console.aws.amazon.com/)，并执行以下操作：
     + 在 Amazon S3 控制台中，移除附加到 的存储桶策略`amzn-s3-demo-bucket1` 在存储桶 **Properties（属性）**中，删除 **Permissions（权限）**部分中的策略。
     + 如果该存储桶是为此练习而创建的，请在 Amazon S3 控制台中删除对象，然后删除存储桶。
     + 在 [IAM 控制台](https://console.aws.amazon.com/iam/)中，删除您在账户 A 中创建的 `examplerole`。有关分步说明，请参阅《IAM 用户指南》**中的[删除 IAM 用户](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_manage.html#id_users_deleting)。
     + 在 [IAM 控制台](https://console.aws.amazon.com/iam/)中，移除 **AccountAadmin** 用户。

1. 使用账户 B 凭证登录 [IAM 控制台](https://console.aws.amazon.com/iam/)。删除用户 **AccountBadmin**。

1. 使用账户 C 凭证登录 [IAM 控制台](https://console.aws.amazon.com/iam/)。删除 **AccountCadmin** 和用户 Dave。

## 相关资源
<a name="RelatedResources-managing-access-example4"></a>

有关本演练的更多信息，请参阅《IAM 用户指南》**中的以下资源：
+ [创建向 IAM 用户委派权限的角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user.html)
+ [教程：使用 IAM 角色委派跨 AWS 账户的访问权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial-cross-account-with-roles.html)
+ [管理 IAM 策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage.html)