

# 配置 ACL
<a name="managing-acls"></a>

本节介绍如何使用访问控制列表（ACL）管理 S3 存储桶和对象的访问权限。您可以使用 Amazon Web Services 管理控制台、Amazon Command Line Interface（CLI)、REST API 或 Amazon SDK 向资源 ACL 添加授权。

存储桶和对象的权限是相互独立的。对象不继承其存储桶的权限。例如，如果您创建了一个存储桶并授予一个用户写入权限，则将无法访问此用户的对象，除非此用户显式授予您访问权限。

您可以向其他 Amazon Web Services 账户用户或预定义的组授予权限。您将向其授予权限的用户或组称作*被授权者*。默认情况下，拥有者（即创建存储桶的 Amazon Web Services 账户）具有完全权限。

您为用户或组授予的每项权限都会在 ACL 中添加一个与该存储桶关联的条目。ACL 列出了授权，这些授权确定了被授权者和授予的权限。

S3 对象所有权是 Amazon S3 存储桶级别的设置，您可以使用该设置来控制上传到存储桶的对象的所有权和禁用或启用 ACL。默认情况下，对象所有权设为强制存储桶拥有者设置，并且所有 ACL 均处于禁用状态。禁用 ACL 后，存储桶拥有者拥有存储桶中的所有对象，并使用访问管理策略来专门管理对这些对象的访问权限。

 Amazon S3 中的大多数现代使用案例不再需要使用 ACL。我们建议您将 ACL 保持为禁用状态，除非有需要单独控制每个对象的访问权限的情况。禁用 ACL 后，您可以使用策略来控制对存储桶中所有对象的访问权限，无论是谁将对象上传到您的存储桶。有关更多信息，请参阅 [为您的存储桶控制对象所有权和禁用 ACL。](about-object-ownership.md)。

**重要**  
如果通用存储桶针对 S3 对象所有权使用强制存储桶拥有者设置，则必须使用策略来授予对通用存储桶及其中对象的访问权限。启用强制存储桶拥有者设置后，设置访问控制列表（ACL）或更新 ACL 的请求将失败并返回 `AccessControlListNotSupported` 错误代码。仍然支持读取 ACL 的请求。

**警告**  
我们强烈建议您避免向**所有人（公有访问）**或**经过身份验证的用户组（所有经 Amazon 身份验证的用户）**群组授予写入访问权限。有关向这些组授予写访问权限的效果的更多信息，请参阅 [Amazon S3 预定义的组](acl-overview.md#specifying-grantee-predefined-groups)。

## 使用 S3 控制台为存储桶设置 ACL 权限
<a name="set-bucket-permissions"></a>

控制台显示重复被授权者的组合访问授权。要查看 ACL 的完整列表，请使用 Amazon S3 REST API、Amazon CLI 或 Amazon SDK。

下表显示了您可以在 Amazon S3 控制台中为存储桶配置的 ACL 权限。


**存储桶的 Amazon S3 控制台 ACL 权限**  

| 控制台权限 | ACL 权限 | 访问 | 
| --- | --- | --- | 
| Objects（对象）– List（列表） | READ | 允许被授权者列出存储桶中的对象 | 
| Objects（对象）— Write（写） | WRITE | 允许被授权者在存储桶中创建新对象。对于现有对象的存储桶和对象所有者，还允许删除和覆写这些对象。 | 
| Bucket ACL（存储桶 ACL）– Read（读取） | READ\$1ACP | 允许被授权者读取存储桶 ACL | 
| BucketACL（存储桶 ACL）— Write（写入） | WRITE\$1ACP | 允许被授权者为适用的存储桶编写 ACL | 
| 所有人（公共访问）：Objects（对象）— List（列表） | READ | 授予存储桶中对象的公共读取访问权限。当您向所有人授予列表访问权限（公共读取权限）时，则任何人都可以访问存储桶中的对象。 | 
| 所有人（公共访问）：Bucket ACL（存储桶 ACL）— Read（读取） | READ\$1ACP | 授予存储桶 ACL 公共读取访问权限。当您向所有人授予读取访问权限（公共访问权限）时，则任何人都可以访问存储桶 ACL。 | 

有关 ACL 权限的更多信息，请参阅 [访问控制列表 (ACL) 概述](acl-overview.md)。

**重要**  
如果通用存储桶针对 S3 对象所有权使用强制存储桶拥有者设置，则必须使用策略来授予对通用存储桶及其中对象的访问权限。启用强制存储桶拥有者设置后，设置访问控制列表（ACL）或更新 ACL 的请求将失败并返回 `AccessControlListNotSupported` 错误代码。仍然支持读取 ACL 的请求。

**为存储桶设置 ACL 权限**

1. 登录到 Amazon Web Services 管理控制台，然后通过以下网址打开 Amazon S3 控制台：[https://console.aws.amazon.com/s3/](https://console.amazonaws.cn/s3/)。

1. 在左侧导航窗格中，选择**通用存储桶**。

1. 在 **Buckets（存储桶）**列表中，请选择要为其配置权限的存储桶的名称。

1. 选择 **Permissions (权限)**。

1. 在 **Access control list (访问控制列表)** 下，请选择 **Edit (编辑)**。

   您可以编辑存储桶的以下 ACL 权限：

**对象**
   + **列出** – 允许被授权者列出存储桶中的对象。
   + **写入** – 允许被授权者在存储桶中创建新对象。对于现有对象的存储桶和对象所有者，还允许删除和覆写这些对象。

     在 S3 控制台中，您只能向 S3 日志传输组和存储桶拥有者（您的 Amazon Web Services 账户）授予写入访问权限。我们强烈建议您不要向其他被授权者授予写入访问权限。但是，如果您需要授予写入访问权限，可以使用 Amazon CLI、Amazon SDK 或 REST API。

**Bucket ACL**
   + **读取** – 允许被授权者读取存储桶 ACL。
   + **写入** – 允许被授权者为适用的存储桶编写 ACL

1. 要更改存储桶拥有者的权限，请在 **Bucket owner（your Amazon Web Services 账户）（存储桶拥有者 [您的 Amazon 账户]）**旁清除或从以下 ACL 权限中选择：
   + **Objects**（对象）– **List**（列出）或 **Write**（写入）
   + **Bucket ACL**（存储桶 ACL）– **Read**（读取）或 **Write**（写入）

   *拥有者*是指 Amazon Web Services 账户根用户，而不是 Amazon Identity and Access Management IAM 用户。有关根用户的更多信息，请参阅《IAM 用户指南》**中的 [Amazon Web Services 账户根用户](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_root-user.html)。

1. 要向公众（互联网上的所有人）授予或撤消权限，请在** 每个人（公共访问）**旁清除或从以下 ACL 权限中选择：
   + **Objects**（对象）– **List**（列表）
   + **Bucket ACL**（存储桶 ACL）– **Read**（读取）
**警告**  
在授予 **Everyone** 组对您的 S3 存储桶的公有访问权限时应谨慎使用。如果您向此组授予访问权限，那么世界上的任何人都可以访问您的存储桶。我们强烈建议您绝对不要授予对 S3 存储桶的任何类型的公有写入权限。

1. 要向拥有 Amazon Web Services 账户的任何人授予或撤消权限，请在 **Authenticated Users group (anyone with an Amazon Web Services 账户) (已经过身份验证的用户组 [拥有 Amazon 账户的任何人])** 旁清除或从以下 ACL 权限中进行选择：
   + **Objects**（对象）– **List**（列表）
   + **Bucket ACL**（存储桶 ACL）– **Read**（读取）

1. 要授予或撤消 Amazon S3 将服务器访问日志写入存储桶的权限，请在 **S3 log delivery group**（S3 日志传输组）下清除或从以下 ACL 权限中进行选择：
   + **Objects**（对象）– **List**（列出）或 **Write**（写入） 
   + **Bucket ACL**（存储桶 ACL）– **Read**（读取）或 **Write**（写入） 

     如果存储桶设置为目标存储桶以接收访问日志，则存储桶权限必须允许**日志传输**组对存储桶有写入权限。当您在存储桶上启用服务器访问日志记录时，Amazon S3 控制台会向 **Log Delivery（日志传输）**组授予对您选择用来接收日志的目标存储桶的写入权限。有关服务器访问日志记录的更多信息，请参阅 [启用 Amazon S3 服务器访问日志记录](enable-server-access-logging.md)。

1. 要授予对其他 Amazon Web Services 账户 的访问权限，请执行以下操作：

   1. 请选择 **Add grantee**（添加被授权者）。

   1. 在 **Grantee (被授权者)** 框中，输入其他 Amazon Web Services 账户的规范 ID。

   1. 从以下 ACL 权限中进行选择：
      + **Objects**（对象）– **List**（列出）或 **Write**（写入）
      + **Bucket ACL**（存储桶 ACL）– **Read**（读取）或 **Write**（写入）
**警告**  
当您需要向其他 Amazon Web Services 账户授权访问您的资源时，注意 Amazon Web Services 账户可以向其账户下的用户授予权限。这称为*跨账户访问*。有关使用跨账户访问的信息，请参阅 *IAM 用户指南*中的[创建角色以向 IAM 用户委派权限](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_roles_create_for-user.html)。

1. 要删除对其他 Amazon Web Services 账户的访问权限，请在 **Access for other Amazon Web Services 账户 (其他 Amazon 账户的访问权限)** 下，请选择 **Remove (删除)**。

1. 要保存您的更改，请选择 **Save Changes (保存更改)**。

## 使用 S3 控制台为对象设置 ACL 权限
<a name="set-object-permissions"></a>

控制台显示重复被授权者的组合访问授权。要查看 ACL 的完整列表，请使用 Amazon S3 REST API、Amazon CLI 或 Amazon SDK。下表显示了您可以在 Amazon S3 控制台中为对象配置的 ACL 权限。


**对象的 Amazon S3 控制台 ACL 权限**  

| 控制台权限 | ACL 权限 | 访问 | 
| --- | --- | --- | 
| Object（对象） — Read（读取） | READ | 允许被授权者读取对象数据及其元数据 | 
| Object ACL（对象 ACL）— Read（读取） | READ\$1ACP | 允许被授权者读取对象 ACL | 
| Object ACL（对象 ACL）— Write（写入） | WRITE\$1ACP | 允许被授权者为适用的对象编写 ACL | 

有关 ACL 权限的更多信息，请参阅 [访问控制列表 (ACL) 概述](acl-overview.md)。

**重要**  
如果通用存储桶针对 S3 对象所有权使用强制存储桶拥有者设置，则必须使用策略来授予对通用存储桶及其中对象的访问权限。启用强制存储桶拥有者设置后，设置访问控制列表（ACL）或更新 ACL 的请求将失败并返回 `AccessControlListNotSupported` 错误代码。仍然支持读取 ACL 的请求。

**为对象设置 ACL 权限**

1. 登录到 Amazon Web Services 管理控制台，然后通过以下网址打开 Amazon S3 控制台：[https://console.aws.amazon.com/s3/](https://console.amazonaws.cn/s3/)。

1. 在 **Bucket（存储桶）**列表中，请选择包含对象的存储桶的名称。

1. 在 **objects**（对象）列表中，请选择要为其设置权限的对象的名称。

1. 请选择 **Permissions**。

1. 在访问控制列表 (ACL) 下，请选择 **Edit (编辑)**。

   您可以编辑对象的以下 ACL 权限：

**对象**
   + **读取** – 允许被授权者读取对象数据及其元数据。

**对象 ACL**
   + **读取** – 允许被授权者读取对象 ACL。
   + **写入** – 允许被授权者为适用的对象编写 ACL。在 S3 控制台中，您只能向存储桶拥有者（您的 Amazon Web Services 账户）授予写入访问权限。我们强烈建议您不要向其他被授权者授予写入访问权限。但是，如果您需要授予写入访问权限，可以使用 Amazon CLI、Amazon SDK 或 REST API。

1. 您可以管理对象的以下访问权限：

   1. 

**对象所有者的访问权限**

      *拥有者*是指 Amazon Web Services 账户根用户，而不是 Amazon Identity and Access Management IAM 用户。有关根用户的更多信息，请参阅《IAM 用户指南》**中的 [Amazon Web Services 账户根用户](https://docs.amazonaws.cn/IAM/latest/UserGuide/id_root-user.html)。

      要更改拥有者的对象访问权限，请在 **Access for object owner (对象所有者的访问权限)** 下，请选择 **Your Amazon Account (owner) (您的 Amazon 账户 [所有者])**。

      选中要更改的权限所对应的复选框，然后选择 **Save (保存)**。

   1. 

**其他 Amazon Web Services 账户的访问权限**

      要向其他 Amazon Web Services 账户 的 Amazon 用户授予权限，请在 **Access for other Amazon Web Services 账户 (其他 Amazon 账户的访问权限)** 下面，请选择 **Add account (添加账户)**。在 **Enter an ID (输入 ID)** 字段中，输入要向其授予对象权限的 Amazon 用户的规范 ID。有关查找规范 ID 的信息，请参阅《Amazon Web Services 一般参考》**中的[您的 Amazon Web Services 账户标识符](https://docs.amazonaws.cn/general/latest/gr/acct-identifiers.html)。您可以添加多达 99 个用户。

      选中要向用户授予的权限所对应的复选框，然后选择 **Save (保存)**。要显示有关权限的信息，请选择帮助图标。

   1. 

**公有访问权限**

      要向一般公众 (世界上的每个人) 授予对您的对象的访问权限，请在 **Public access (公开访问)** 下面选择 **Everyone (所有人)**。授予公有访问权限意味着世界上的任何人都可以访问该对象。

      选中要授予的权限所对应的复选框，然后选择 **Save (保存)**。
**警告**  
在授予 **Everyone (所有人)** 组对您的 Amazon S3 对象的匿名访问权限时应谨慎使用。如果您向此组授予访问权限，那么世界上的任何人都可以访问您的对象。如果您需要为所有人授予访问权限，我们强烈建议您仅授予**读取对象**的权限。
我们强烈建议您*不要*为 **Everyone (所有人)** 组授予写入对象权限。这样做将允许任何人覆盖对象的 ACL 权限。

## 使用 Amazon 开发工具包
<a name="acl-using-sdk"></a>

本节提供了有关如何在存储桶和对象上配置访问控制列表 (ACL) 授予的示例。

**重要**  
如果通用存储桶针对 S3 对象所有权使用强制存储桶拥有者设置，则必须使用策略来授予对通用存储桶及其中对象的访问权限。启用强制存储桶拥有者设置后，设置访问控制列表（ACL）或更新 ACL 的请求将失败并返回 `AccessControlListNotSupported` 错误代码。仍然支持读取 ACL 的请求。

------
#### [ Java ]

本节提供了有关如何在存储桶和对象上配置访问控制列表（ACL）授予的示例。第一个示例将创建具有标准 ACL（请参阅[标准 ACL](acl-overview.md#canned-acl)）的存储桶，创建自定义权限授予列表，然后将标准 ACL 替换为包含自定义授予的 ACL。第二个示例演示如何使用 `AccessControlList.grantPermission()` 方法修改 ACL。

**Example 创建存储桶并指定用于向 S3 日志传输组授予权限的标准 ACL**  
此示例将创建一个存储桶。在请求中，此示例指定了一个标准 ACL，该 ACL 向日志传输组授予将日志写入到存储桶的权限。  

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;

import java.io.IOException;
import java.util.ArrayList;

public class CreateBucketWithACL {

    public static void main(String[] args) throws IOException {
        Regions clientRegion = Regions.DEFAULT_REGION;
        String bucketName = "*** Bucket name ***";
        String userEmailForReadPermission = "*** user@example.com ***";

        try {
            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withRegion(clientRegion)
                    .build();

            // Create a bucket with a canned ACL. This ACL will be replaced by the
            // setBucketAcl()
            // calls below. It is included here for demonstration purposes.
            CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName, clientRegion.getName())
                    .withCannedAcl(CannedAccessControlList.LogDeliveryWrite);
            s3Client.createBucket(createBucketRequest);

            // Create a collection of grants to add to the bucket.
            ArrayList<Grant> grantCollection = new ArrayList<Grant>();

            // Grant the account owner full control.
            Grant grant1 = new Grant(new CanonicalGrantee(s3Client.getS3AccountOwner().getId()),
                    Permission.FullControl);
            grantCollection.add(grant1);

            // Grant the LogDelivery group permission to write to the bucket.
            Grant grant2 = new Grant(GroupGrantee.LogDelivery, Permission.Write);
            grantCollection.add(grant2);

            // Save grants by replacing all current ACL grants with the two we just created.
            AccessControlList bucketAcl = new AccessControlList();
            bucketAcl.grantAllPermissions(grantCollection.toArray(new Grant[0]));
            s3Client.setBucketAcl(bucketName, bucketAcl);

            // Retrieve the bucket's ACL, add another grant, and then save the new ACL.
            AccessControlList newBucketAcl = s3Client.getBucketAcl(bucketName);
            Grant grant3 = new Grant(new EmailAddressGrantee(userEmailForReadPermission), Permission.Read);
            newBucketAcl.grantAllPermissions(grant3);
            s3Client.setBucketAcl(bucketName, newBucketAcl);
        } catch (AmazonServiceException e) {
            // The call was transmitted successfully, but Amazon S3 couldn't process
            // it and returned an error response.
            e.printStackTrace();
        } catch (SdkClientException e) {
            // Amazon S3 couldn't be contacted for a response, or the client
            // couldn't parse the response from Amazon S3.
            e.printStackTrace();
        }
    }
}
```

**Example 更新现有对象的 ACL**  
此示例将更新对象上的 ACL。该示例执行以下任务：  
+ 检索对象的 ACL
+ 通过删除所有现有权限来清除该 ACL
+ 添加两个权限：对所有者的完全访问权限以及对通过电子邮件地址标识的用户的 WRITE\$1ACP 权限 (请参阅 [我能授予哪些许可？](acl-overview.md#permissions))。
+ 将 ACL 保存到对象

```
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.AccessControlList;
import com.amazonaws.services.s3.model.CanonicalGrantee;
import com.amazonaws.services.s3.model.EmailAddressGrantee;
import com.amazonaws.services.s3.model.Permission;

import java.io.IOException;

public class ModifyACLExistingObject {

    public static void main(String[] args) throws IOException {
        Regions clientRegion = Regions.DEFAULT_REGION;
        String bucketName = "*** Bucket name ***";
        String keyName = "*** Key name ***";
        String emailGrantee = "*** user@example.com ***";

        try {
            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withCredentials(new ProfileCredentialsProvider())
                    .withRegion(clientRegion)
                    .build();

            // Get the existing object ACL that we want to modify.
            AccessControlList acl = s3Client.getObjectAcl(bucketName, keyName);

            // Clear the existing list of grants.
            acl.getGrantsAsList().clear();

            // Grant a sample set of permissions, using the existing ACL owner for Full
            // Control permissions.
            acl.grantPermission(new CanonicalGrantee(acl.getOwner().getId()), Permission.FullControl);
            acl.grantPermission(new EmailAddressGrantee(emailGrantee), Permission.WriteAcp);

            // Save the modified ACL back to the object.
            s3Client.setObjectAcl(bucketName, keyName, acl);
        } catch (AmazonServiceException e) {
            // The call was transmitted successfully, but Amazon S3 couldn't process
            // it, so it returned an error response.
            e.printStackTrace();
        } catch (SdkClientException e) {
            // Amazon S3 couldn't be contacted for a response, or the client
            // couldn't parse the response from Amazon S3.
            e.printStackTrace();
        }
    }
}
```

------
#### [ .NET ]

**Example 创建存储桶并指定用于向 S3 日志传输组授予权限的标准 ACL**  
此 C\$1 示例将创建一个存储桶。在请求中，代码还将指定一个标准 ACL，该 ACL 向日志传输组授予将日志写入到存储桶的权限。  
 有关设置和运行代码示例的信息，请参阅《适用于 .NET 的 Amazon SDK 开发人员指南》**中的[适用于 .NET 的 Amazon SDK 入门](https://docs.amazonaws.cn/sdk-for-net/latest/developer-guide/net-dg-setup.html)。  

```
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.Threading.Tasks;

namespace Amazon.DocSamples.S3
{
    class ManagingBucketACLTest
    {
        private const string newBucketName = "*** bucket name ***"; 
        // Specify your bucket region (an example region is shown).
        private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
        private static IAmazonS3 client;

        public static void Main()
        {
            client = new AmazonS3Client(bucketRegion);
            CreateBucketUseCannedACLAsync().Wait();
        }

        private static async Task CreateBucketUseCannedACLAsync()
        {
            try
            {
                // Add bucket (specify canned ACL).
                PutBucketRequest putBucketRequest = new PutBucketRequest()
                {
                    BucketName = newBucketName,
                    BucketRegion = S3Region.EUW1, // S3Region.US,
                                                  // Add canned ACL.
                    CannedACL = S3CannedACL.LogDeliveryWrite
                };
                PutBucketResponse putBucketResponse = await client.PutBucketAsync(putBucketRequest);

                // Retrieve bucket ACL.
                GetACLResponse getACLResponse = await client.GetACLAsync(new GetACLRequest
                {
                    BucketName = newBucketName
                });
            }
            catch (AmazonS3Exception amazonS3Exception)
            {
                Console.WriteLine("S3 error occurred. Exception: " + amazonS3Exception.ToString());
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception: " + e.ToString());
            }
        }
    }
}
```

**Example 更新现有对象的 ACL**  
此 C\$1 示例将更新现有对象上的 ACL。该示例执行以下任务：  
+ 检索对象的 ACL。
+ 通过删除所有现有权限来清除该 ACL。
+ 添加两个权限：对所有者的完全访问权限以及对通过电子邮件地址标识的用户的 WRITE\$1ACP 权限。
+ 通过发送 `PutAcl` 请求来保存该 ACL。
有关设置和运行代码示例的信息，请参阅《适用于 .NET 的 Amazon SDK 开发人员指南》**中的[适用于 .NET 的 Amazon SDK 入门](https://docs.amazonaws.cn/sdk-for-net/latest/developer-guide/net-dg-setup.html)。  

```
using Amazon;
using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Amazon.DocSamples.S3
{
    class ManagingObjectACLTest
    {
        private const string bucketName = "*** bucket name ***"; 
        private const string keyName = "*** object key name ***"; 
        private const string emailAddress = "*** email address ***";
        // Specify your bucket region (an example region is shown).
        private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2;
        private static IAmazonS3 client;
        public static void Main()
        {
            client = new AmazonS3Client(bucketRegion);
            TestObjectACLTestAsync().Wait();
        }
        private static async Task TestObjectACLTestAsync()
        {
            try
            {
                    // Retrieve the ACL for the object.
                    GetACLResponse aclResponse = await client.GetACLAsync(new GetACLRequest
                    {
                        BucketName = bucketName,
                        Key = keyName
                    });

                    S3AccessControlList acl = aclResponse.AccessControlList;

                    // Retrieve the owner (we use this to re-add permissions after we clear the ACL).
                    Owner owner = acl.Owner;

                    // Clear existing grants.
                    acl.Grants.Clear();

                    // Add a grant to reset the owner's full permission (the previous clear statement removed all permissions).
                    S3Grant fullControlGrant = new S3Grant
                    {
                        Grantee = new S3Grantee { CanonicalUser = owner.Id },
                        Permission = S3Permission.FULL_CONTROL
                        
                    };

                    // Describe the grant for the permission using an email address.
                    S3Grant grantUsingEmail = new S3Grant
                    {
                        Grantee = new S3Grantee { EmailAddress = emailAddress },
                        Permission = S3Permission.WRITE_ACP
                    };
                    acl.Grants.AddRange(new List<S3Grant> { fullControlGrant, grantUsingEmail });
 
                    // Set a new ACL.
                    PutACLResponse response = await client.PutACLAsync(new PutACLRequest
                    {
                        BucketName = bucketName,
                        Key = keyName,
                        AccessControlList = acl
                    });
            }
            catch (AmazonS3Exception amazonS3Exception)
            {
                Console.WriteLine("An AmazonS3Exception was thrown. Exception: " + amazonS3Exception.ToString());
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception: " + e.ToString());
            }
        }
    }
}
```

------

## 使用 REST API
<a name="acl-using-rest-api"></a>

Amazon S3 API 使您可以在创建存储段或对象时设置 ACL。Amazon S3 还提供 API 以在现有存储段或对象上设置 ACL。这些 API 提供了以下方法来设置 ACL：
+ **使用请求标头设置 ACL** — 发送创建资源（存储桶或对象）的请求时，您可以使用请求标头设置 ACL。使用这些标头时，您可以指定一个标准 ACL 或者显式指定授权 (显式识别被授权者和许可)。
+ **使用请求正文设置 ACL** — 当您发送在现有资源上设置 ACL 的请求时，您可以在请求标头或正文中设置 ACL。

有关管理 ACL 的 REST API 支持的信息，请参阅 *Amazon Simple Storage Service API 参考*中的以下部分：
+  [GetBucketAcl](https://docs.amazonaws.cn/AmazonS3/latest/API/RESTBucketGETacl.html) 
+  [PutBucketAcl](https://docs.amazonaws.cn/AmazonS3/latest/API/RESTBucketPUTacl.html) 
+  [GetObjectAcl](https://docs.amazonaws.cn/AmazonS3/latest/API/RESTObjectGETacl.html) 
+  [PutObjectAcl](https://docs.amazonaws.cn/AmazonS3/latest/API/RESTObjectPUTacl.html) 
+  [PutObject](https://docs.amazonaws.cn/AmazonS3/latest/API/RESTObjectPUT.html) 
+  [:CreateBucket](https://docs.amazonaws.cn/AmazonS3/latest/API/RESTBucketPUT.html) 
+  [CopyObject](https://docs.amazonaws.cn/AmazonS3/latest/API/RESTObjectCOPY.html) 
+  [CreateMultipartUpload](https://docs.amazonaws.cn/AmazonS3/latest/API/mpUploadInitiate.html) 

**重要**  
如果通用存储桶针对 S3 对象所有权使用强制存储桶拥有者设置，则必须使用策略来授予对通用存储桶及其中对象的访问权限。启用强制存储桶拥有者设置后，设置访问控制列表（ACL）或更新 ACL 的请求将失败并返回 `AccessControlListNotSupported` 错误代码。仍然支持读取 ACL 的请求。

### 访问控制列表 (ACL) 特定的请求标头
<a name="acl-headers-rest-api"></a>

您可以使用标头授予基于访问控制列表 (ACL) 的权限。默认情况下，所有的对象都是私有的。只有所有者具有完全访问权限控制。添加新的对象时，您可以向单个 Amazon Web Services 账户或 Amazon S3 定义的预定义组授予权限。然后，这些权限将添加到对象上的访问控制列表 (ACL)。有关更多信息，请参阅 [访问控制列表 (ACL) 概述](acl-overview.md)。

通过此操作，您可以使用以下两种方法之一授予访问权限：
+ **标准 ACL (`x-amz-acl`)** — Amazon S3 支持一系列预定义的 ACL，称为标准 ACL。每个标准 ACL 都有一组预定义的被授权者和许可。有关更多信息，请参阅 [标准 ACL](acl-overview.md#canned-acl)。
+ **访问权限** – 要向特定 Amazon Web Services 账户 或组显式授予访问权限，请使用以下标头。每个标头映射到 Amazon S3 在 ACL 中支持的特定权限。有关更多信息，请参阅 [访问控制列表 (ACL) 概述](acl-overview.md)。在标头中，您可以指定获得特定权限的被授权者的列表。
  + x-amz-grant-read
  + x-amz-grant-write
  + x-amz-grant-read-acp
  + x-amz-grant-write-acp
  + x-amz-grant-full-control

## 使用 Amazon CLI
<a name="using-acl-cli"></a>

有关使用 Amazon CLI 管理 ACL 的更多信息，请参阅 *Amazon CLI 命令参考*中的 [put-bucket-acl](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-bucket-acl.html)。

**重要**  
如果通用存储桶针对 S3 对象所有权使用强制存储桶拥有者设置，则必须使用策略来授予对通用存储桶及其中对象的访问权限。启用强制存储桶拥有者设置后，设置访问控制列表（ACL）或更新 ACL 的请求将失败并返回 `AccessControlListNotSupported` 错误代码。仍然支持读取 ACL 的请求。