

# 使用存储桶拥有者条件验证存储桶所有权
<a name="bucket-owner-condition"></a>

Amazon S3 存储桶拥有者条件可确保您在 S3 操作中使用的存储桶属于您期望的 AWS 账户。

大多数 S3 操作从特定 S3 存储桶读取或写入特定 S3 存储桶。这些操作包括上传、复制和下载对象、检索或修改存储桶配置以及检索或修改对象配置。执行这些操作时，您可以通过在请求中包含存储桶名称来指定要使用的存储桶。例如，要从 S3 检索对象，您需要发出一个请求，指定存储桶的名称和要从该存储桶中检索的对象键。

由于 Amazon S3 会根据存储桶的名称识别存储桶，因此在请求中使用错误存储桶名称的应用程序可能会无意中对非预期存储桶执行操作。为了帮助避免此类情况下的意外存储桶交互，您可以使用*存储桶拥有者条件*。存储桶拥有者条件使您能够验证目标存储桶是否由预期 AWS 账户拥有，从而为 S3 操作具有预期效果提供了额外保证。

**Topics**
+ [

## 何时使用存储桶拥有者条件
](#bucket-owner-condition-when-to-use)
+ [

## 验证存储桶拥有者
](#bucket-owner-condition-use)
+ [

## 示例
](#bucket-owner-condition-examples)
+ [

## 限制和局限性
](#bucket-owner-condition-restrictions-limitations)

## 何时使用存储桶拥有者条件
<a name="bucket-owner-condition-when-to-use"></a>

我们建议您在执行受支持的 S3 操作并知道预期存储桶拥有者的账户 ID 时使用存储桶拥有者条件。存储桶拥有者条件适用于所有 S3 对象操作和大多数 S3 存储桶操作。有关不支持存储桶拥有者条件的 S3 操作的列表，请参阅 [限制和局限性](#bucket-owner-condition-restrictions-limitations)。

要了解使用存储桶拥有者条件的好处，请考虑以下涉及 AWS 客户 Bea 的场景：

1. Bea 开发使用 Amazon S3 的应用程序。在开发过程中，Bea 使用仅限测试的 AWS 账户创建名为 `bea-data-test` 的存储桶，并将其应用程序配置为向 `bea-data-test` 发出请求。

1. Bea 部署其应用程序，但忘记将应用程序重新配置为使用其生产 AWS 账户中的存储桶。

1. 在生产中，Bea 的应用程序向 `bea-data-test` 发出请求，这成功了。这导致生产数据写入 Bea 测试账户中的存储桶。

Bea 可以通过使用存储桶拥有者条件来帮助防范此类情况。使用存储桶拥有者条件，Bea 可以在其请求中包含预期存储桶拥有者的 AWS 账户 ID。然后，Amazon S3 在处理每个请求之前检查存储桶拥有者的账户 ID。如果实际存储桶拥有者与预期存储桶拥有者不匹配，则请求将失败。

如果 Bea 使用存储桶拥有者条件，则之前描述的场景不会导致 Bea 的应用程序无意中写入测试存储桶。她的应用程序在步骤 3 中发出的请求将失败，并显示 `Access Denied` 错误消息。通过使用存储桶拥有者条件，Bea 帮助消除意外与错误 AWS 账户 中的存储桶交互的风险。

## 验证存储桶拥有者
<a name="bucket-owner-condition-use"></a>

要使用存储桶拥有者条件，请在请求中包含一个参数，用于指定预期存储桶拥有者。大多数 S3 操作仅涉及单个存储桶，并且只需此单个参数即可使用存储桶拥有者条件。对于 `CopyObject` 操作，此第一个参数指定目标存储桶的预期拥有者，您包含第二个参数来指定源存储桶的预期拥有者。

当您发出包含存储桶拥有者条件参数的请求时，S3 会在处理该请求之前根据指定参数检查存储桶拥有者的账户 ID。如果参数与存储桶拥有者的账户 ID 匹配，S3 将处理该请求。如果参数与存储桶拥有者的账户 ID 不匹配，则该请求将失败并显示 `Access Denied` 错误消息。

您可以通过 AWS Command Line Interface（AWS CLI）、AWS SDK 和 Amazon S3 REST API 来使用存储桶拥有者条件。通过 AWS CLI 和 Amazon S3 REST API 使用存储桶拥有者条件时，请使用以下参数名称。


****  

| 访问方法 | 用于非复制操作的参数 | 复制操作源参数 | 复制操作目标参数 | 
| --- | --- | --- | --- | 
| AWS CLI | --expected-bucket-owner | --expected-source-bucket-owner | --expected-bucket-owner | 
| Amazon S3 REST API | x-amz-expected-bucket-owner 标头 | x-amz-source-expected-bucket-owner 标头 | x-amz-expected-bucket-owner 标头 | 

通过 AWS SDK 使用存储桶拥有者条件所需的参数名称因语言而异。要确定所需的参数，请参阅所需语言的 SDK 文档。您可以在[用于在 AWS 上进行构建的工具](https://aws.amazon.com/tools/)中找到 SDK 文档。

## 示例
<a name="bucket-owner-condition-examples"></a>

以下示例演示如何使用 AWS CLI 或 AWS SDK for Java 2.x 在 Amazon S3 中实施存储桶拥有者条件。

**Example**  
***示例：上传对象***  
以下示例将对象上传到 S3 存储桶`amzn-s3-demo-bucket1`，使用存储桶拥有者条件来确保 `amzn-s3-demo-bucket1` 由 AWS 账户 `111122223333` 拥有。  

```
aws s3api put-object \
                 --bucket amzn-s3-demo-bucket1 --key exampleobject --body example_file.txt \
                 --expected-bucket-owner 111122223333
```

```
public void putObjectExample() {
    S3Client s3Client = S3Client.create();;
    PutObjectRequest request = PutObjectRequest.builder()
            .bucket("amzn-s3-demo-bucket1")
            .key("exampleobject")
            .expectedBucketOwner("111122223333")
            .build();
    Path path = Paths.get("example_file.txt");
    s3Client.putObject(request, path);
}
```

**Example**  
***示例：复制对象***  
以下示例将对象 `object1` 从 S3 存储桶`amzn-s3-demo-bucket1` 复制到 S3 存储桶`amzn-s3-demo-bucket2`。根据下表，它使用存储桶拥有者条件来确保存储桶由预期账户拥有。  


****  

| 存储桶 | 预期拥有者 | 
| --- | --- | 
| amzn-s3-demo-bucket1 | 111122223333 | 
| amzn-s3-demo-bucket2 | 444455556666 | 

```
aws s3api copy-object --copy-source amzn-s3-demo-bucket1/object1 \
                            --bucket amzn-s3-demo-bucket2 --key object1copy \
                            --expected-source-bucket-owner 111122223333 --expected-bucket-owner 444455556666
```

```
public void copyObjectExample() {
        S3Client s3Client = S3Client.create();
        CopyObjectRequest request = CopyObjectRequest.builder()
                .copySource("amzn-s3-demo-bucket1/object1")
                .destinationBucket("amzn-s3-demo-bucket2")
                .destinationKey("object1copy")
                .expectedSourceBucketOwner("111122223333")
                .expectedBucketOwner("444455556666")
                .build();
        s3Client.copyObject(request);
    }
```

**Example**  
***示例：检索存储桶策略***  
以下示例检索 S3 存储桶`amzn-s3-demo-bucket1` 的访问策略，使用存储桶拥有者条件来确保 `amzn-s3-demo-bucket1` 由 AWS 账户 `111122223333` 拥有。  

```
aws s3api get-bucket-policy --bucket amzn-s3-demo-bucket1 --expected-bucket-owner 111122223333
```

```
public void getBucketPolicyExample() {
    S3Client s3Client = S3Client.create();
    GetBucketPolicyRequest request = GetBucketPolicyRequest.builder()
            .bucket("amzn-s3-demo-bucket1")
            .expectedBucketOwner("111122223333")
            .build();
    try {
        GetBucketPolicyResponse response = s3Client.getBucketPolicy(request);
    }
    catch (S3Exception e) {
        // The call was transmitted successfully, but Amazon S3 couldn't process 
        // it, so it returned an error response.
        e.printStackTrace();
    }
}
```

## 限制和局限性
<a name="bucket-owner-condition-restrictions-limitations"></a>

Amazon S3 存储桶拥有者条件具有以下限制和局限性：
+ 存储桶拥有者条件参数的值必须是 AWS 账户 ID（12 位字母数字值）。不支持服务主体。
+ 存储桶拥有者条件不适用于 [CreateBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html)、[ListBuckets](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html) 或 [AWS S3 控制](https://docs.aws.amazon.com/AmazonS3/latest/API/API_Operations_AWS_S3_Control.html)中包含的任何操作。Amazon S3 将忽略对这些操作的请求中包含的任何存储桶拥有者条件参数。
+ 存储桶拥有者条件仅验证在验证参数中指定的账户是否拥有该存储桶。存储桶拥有者条件不检查存储桶的配置。它也不能保证存储桶的配置符合任何特定条件或与任何过去的状态匹配。