

# 示例 3：存储桶拥有者授予不属于自己的对象的权限
<a name="example-walkthroughs-managing-access-example3"></a>

**重要**  
向 IAM 角色授予权限是比向各个用户授予权限更好的做法。若要了解如何执行此操作，请参阅[了解跨账户权限和使用 IAM 角色](example-walkthroughs-managing-access-example4.md#access-policies-walkthrough-example4-overview)。

**Topics**
+ [步骤 0：准备演练](#access-policies-walkthrough-cross-account-acl-step0)
+ [步骤 1：执行账户 A 任务](#access-policies-walkthrough-cross-account-acl-acctA-tasks)
+ [步骤 2：执行账户 B 任务](#access-policies-walkthrough-cross-account-acl-acctB-tasks)
+ [步骤 3：测试权限](#access-policies-walkthrough-cross-account-acl-verify)
+ [步骤 4：清除](#access-policies-walkthrough-cross-account-acl-cleanup)

此示例的情况是，存储桶拥有者要授予对象访问权限，但该存储桶拥有者并未拥有该存储桶中的所有对象。在此示例中，存储桶拥有者想要向其账户中的用户授予权限。

存储桶拥有者可让其他 AWS 账户上传对象。默认情况下，存储桶拥有者不拥有 AWS 账户 写入存储桶的对象。对象归将它们写入 S3 存储桶的账户所有。如果存储桶拥有者未拥有存储桶中的对象，对象拥有者必须首先使用对象访问控制列表（ACL）授予存储桶拥有者权限。然后，存储桶拥有者可以授予他们未拥有的对象的权限。有关更多信息，请参阅 [Amazon S3 存储桶和对象所有权](access-policy-language-overview.md#about-resource-owner)。

如果存储桶拥有者对存储桶的 S3 对象所有权应用了强制存储桶拥有者设置，则存储桶拥有者将拥有存储桶中的所有对象，包括另一个 AWS 账户 所编写的对象。此方法将解决存储桶拥有者未拥有对象的问题。然后，您可以将权限委派给自己账户中的用户或其他 AWS 账户。

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

在此示例中，我们假设存储桶拥有者尚未应用对象所有权的强制存储桶拥有者设置。存储桶拥有者向其账户中的用户委派权限。下面概括介绍演练步骤：

![\[存储桶拥有者授予其未拥有的对象的权限\]](http://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/images/access-policy-ex3.png)


1. 账户 A 管理员用户使用两条语句来附加存储桶策略。
   + 向账户 B 授予跨账户上传对象的权限。
   + 允许用户使用自己的账户访问存储桶中的对象。

1. 账户 B 管理员用户将对象上传至账户 A 拥有的存储桶。

1. 账户 B 管理员将更新对象 ACL，在其中添加授权，以向存储桶拥有者授予对于该对象的完全控制权限。

1. 账户 A 中的用户将通过访问存储桶中的对象（而不管谁拥有它们）来验证权限。

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


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

创建用户和授予权限的所有任务都在 AWS 管理控制台 中完成。为验证权限，演练中使用命令行工具、AWS Command Line Interface (AWS CLI) 和 AWS Tools for Windows PowerShell，因此您无需编写任何代码。

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

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

   1. 根据需要注册 AWS 账户。

   1. 使用账户 A 凭证登录 [IAM 控制台](https://console.aws.amazon.com/iam/)，然后执行以下操作以创建管理员用户：
      + 创建用户 **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 控制台](https://console.aws.amazon.com/iam/)的**控制面板**中，记下 **IAM 用户登录 URL**。此账户中的用户必须在登录 AWS 管理控制台 时使用此 URL。有关更多信息，请参阅 *IAM 用户指南*中的[用户如何登录您的账户](https://docs.aws.amazon.com/IAM/latest/UserGuide/getting-started_how-users-sign-in.html)。

   1. 使用账户 B 凭证重复上一个步骤，然后创建管理员用户 **AccountBadmin**。

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

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

## 步骤 1：执行账户 A 任务
<a name="access-policies-walkthrough-cross-account-acl-acctA-tasks"></a>

对账户 A 执行以下步骤：

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

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

### 步骤 1.2：创建存储桶和用户，并添加一条授予用户权限的存储桶策略
<a name="access-policies-walkthrough-cross-account-acl-create-bucket"></a>

1. 在 Amazon S3 控制台中创建一个存储桶。此练习假设该存储桶在美国东部（弗吉尼亚州北部）AWS 区域创建，名称为 `amzn-s3-demo-bucket1`。

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

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

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

1. 记下用户 Dave 的凭证。

1. 在 Amazon S3 控制台中，将以下存储桶策略附加到 `amzn-s3-demo-bucket1` 存储桶。有关说明，请参阅[使用 Amazon S3 控制台添加存储桶策略](add-bucket-policy.md)。按照这些步骤添加存储桶策略。有关如何查找账户 ID 的信息，请参阅[查找您的 AWS 账户 ID](https://docs.aws.amazon.com/general/latest/gr/acct-identifiers.html#FindingYourAccountIdentifiers)。

   该策略将向账户 B 授予 `s3:PutObject` 和 `s3:ListBucket` 权限。该策略还为用户 `Dave` 授予了 `s3:GetObject` 权限。

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "Statement1",
               "Effect": "Allow",
               "Principal": {
                   "AWS": "arn:aws:iam::111122223333:root"
               },
               "Action": [
                   "s3:PutObject",
                   "s3:ListBucket"
               ],
               "Resource": [
                   "arn:aws:s3:::amzn-s3-demo-bucket1/*",
                   "arn:aws:s3:::amzn-s3-demo-bucket1"
               ]
           },
           {
               "Sid": "Statement3",
               "Effect": "Allow",
               "Principal": {
                   "AWS": "arn:aws:iam::111122223333:user/Dave"
               },
               "Action": [
                   "s3:GetObject"
               ],
               "Resource": [
                   "arn:aws:s3:::amzn-s3-demo-bucket1/*"
               ]
           }
       ]
   }
   ```

------

## 步骤 2：执行账户 B 任务
<a name="access-policies-walkthrough-cross-account-acl-acctB-tasks"></a>

现在账户 B 有权对账户 A 的存储桶执行操作，账户 B 管理员将执行以下操作：
+ 将对象上传到账户 A 的存储桶。
+ 在对象 ACL 中添加授权，向账户 A（存储桶拥有者）授予完全控制权限。

**使用 AWS CLI**

1. 使用 `put-object` AWS CLI 命令，上传对象。该命令中的 `--body` 参数指示要上传的源文件。例如，如果该文件在 Windows 计算机上的 `C:` 驱动器中，您应指定 `c:\HappyFace.jpg`。`--key` 参数提供对象的键名。

   ```
   aws s3api put-object --bucket amzn-s3-demo-bucket1 --key HappyFace.jpg --body HappyFace.jpg --profile AccountBadmin
   ```

1. 在对象 ACL 中添加一个授权，向存储桶拥有者授予对于对象的完全控制权。有关如何查找规范用户 ID 的信息，请参阅《AWS 账户管理参考指南》**中的 [Find the canonical user ID for your AWS 账户](https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-identifiers.html#FindCanonicalId)。

   ```
   aws s3api put-object-acl --bucket amzn-s3-demo-bucket1 --key HappyFace.jpg --grant-full-control id="AccountA-CanonicalUserID" --profile AccountBadmin
   ```

**使用 Tools for Windows PowerShell**

1. 使用 `Write-S3Object` 命令，上传对象。

   ```
   Write-S3Object -BucketName amzn-s3-demo-bucket1 -key HappyFace.jpg -file HappyFace.jpg -StoredCredentials AccountBadmin
   ```

1. 在对象 ACL 中添加一个授权，向存储桶拥有者授予对于对象的完全控制权。

   ```
   Set-S3ACL -BucketName amzn-s3-demo-bucket1 -Key HappyFace.jpg -CannedACLName "bucket-owner-full-control" -StoredCreden
   ```

## 步骤 3：测试权限
<a name="access-policies-walkthrough-cross-account-acl-verify"></a>

现在验证账户 A 中的用户 Dave 是否能够访问账户 B 拥有的对象。

**使用 AWS CLI**

1. 将用户 Dave 的凭证添加到 AWS CLI 配置文件，并创建新的配置文件 `UserDaveAccountA`。有关更多信息，请参阅 [设置用于演练的工具](policy-eval-walkthrough-download-awscli.md)。

   ```
   [profile UserDaveAccountA]
   aws_access_key_id = access-key
   aws_secret_access_key = secret-access-key
   region = us-east-1
   ```

1. 运行 `get-object` CLI 命令，下载 `HappyFace.jpg`，并将它保存在本地。您可以通过添加参数 `--profile` 为用户 Dave 提供凭证。

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

**使用 Tools for Windows PowerShell**

1. 将用户 Dave 的 AWS 凭证以 `UserDaveAccountA` 的身份保存到持久存储。

   ```
   Set-AWSCredentials -AccessKey UserDave-AccessKey -SecretKey UserDave-SecretAccessKey -storeas UserDaveAccountA
   ```

1. 运行 `Read-S3Object` 命令，下载 `HappyFace.jpg` 对象，并将它保存在本地。您可以通过添加参数 `-StoredCredentials` 为用户 Dave 提供凭证。

   ```
   Read-S3Object -BucketName amzn-s3-demo-bucket1 -Key HappyFace.jpg -file HappyFace.jpg  -StoredCredentials UserDaveAccountA
   ```

## 步骤 4：清除
<a name="access-policies-walkthrough-cross-account-acl-cleanup"></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/)中，移除 **AccountAadmin** 用户。有关分步说明，请参阅《IAM 用户指南》**中的[删除 IAM 用户](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_manage.html#id_users_deleting)。

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