如何授予对 Amazon S3 存储桶中某些对象的公共读取访问权限?
我希望我的 Amazon Simple Storage Service (Amazon S3) 存储桶中的某些对象可以被公开读取。但是,我不想更改同一存储桶中其他对象的权限。
简短描述
使用以下方式之一授予对您的 S3 存储桶中对象的公共读取访问权限:
- 使用 Amazon S3 控制台更新对象的访问控制列表 (ACL)。
- 使用 AWS 命令行界面 (AWS CLI) 更新对象的 ACL。
- 使用存储桶策略授予对特定对象标签的公共读取访问权限。
- 使用存储桶策略授予对特定前缀的公共读取访问权限。
重要事项:当您在存储桶上将 S3 对象所有权设置为强制存储桶所有者时,您将无法使用存储桶和对象 ACL 授予公共访问权限。在大多数情况下,您不需要通过 ACL 来授予对对象和存储桶的权限。相反,您可以使用 AWS Identity Access and Management (IAM) 策略和 S3 存储桶策略来授予权限。
默认情况下,新的存储桶、接入点和对象不允许公共访问。如果您为 AWS 账户内的所有存储桶均配置了屏蔽公共访问权限,则您会收到“Bucket and objects not public”(存储桶和对象未公开)消息。
要访问公共存储桶,请确保您的网络中未配置阻止出站流量流向存储桶域的防火墙或设置。
解决方法
**重要事项:**默认情况下,新 S3 存储桶上的屏蔽公共访问权限设置为 True。在开始之前,请在账户级别或存储桶级别将屏蔽公共访问权限设置更改为 False。
使用 Amazon S3 控制台更新对象的 ACL
同时公开多个对象
**警告:**在公开对象之前,请仔细检查这些对象。公开多个对象后,无法同时对所有对象撤销此操作。相反,您必须在每个对象的 Permissions(权限)选项卡中修改 Public access(公共访问权限)。
要同时公开多个对象,请完成以下步骤:
- 打开 Amazon S3 控制台,然后选择要公开的对象。
- 选择 Actions(操作),然后选择 Make public(公开)。
- 在 Make public(公开)对话框中,确认对象列表正确无误。
- 选择 Make public(公开)。
公开一个对象
要仅公开一个对象,请重复前面的过程或完成以下步骤:
- 打开 Amazon S3 控制台,然后选择要公开的对象对应的存储桶。
- 在 Objects(对象)中,选择该对象。
- 选择 Permissions(权限)选项卡,然后选择 Edit(编辑)。
- 在 Everyone(所有人)部分中,选择 Objects Read(对象读取)。
- 选择 I understand the effects of these changes on this object(我了解这些更改对该对象的影响)。
- 选择 Save changes(保存更改)。
使用 AWS CLI 更新对象的 ACL
**注意:**如果您在运行 AWS CLI 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI。
对于已经存储在 Amazon S3 中的对象,您可以运行 put-object-acl 命令来更新该对象的 ACL 以获得公共读取访问权限:
aws s3api put-object-acl --bucket DOC-EXAMPLE-BUCKET --key exampleobject --acl public-read
**注意:**请将 exampleobject 替换为您的对象。
或者,您可以运行以下 put-object-acl 命令,以向账户所有者授予对该对象的完全控制权,并向其他所有人授予读取访问权限:
aws s3api put-object-acl --bucket DOC-EXAMPLE-BUCKET --key exampleobject --grant-full-control id="008exampleA45666666668889999008853" --grant-read uri=http://acs.amazonaws.com/groups/global/AllUsers
**注意:**对于 grant-full-control id,请输入账户的规范用户 ID。
使用存储桶策略授予对特定对象标签的公共读取访问权限
**重要事项:**在开始之前,请务必查看针对对象标记的 Amazon S3 定价。
要使用策略授予对具有特定标签的对象的公共读取访问权限,请完成以下步骤:
-
添加存储桶策略,以允许对具有特定标签的所有对象进行公共读取访问。例如,以下策略允许对任何具有 public=yes 键值对标签的对象进行公共读取访问:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*", "Condition": { "StringEquals": { "s3:ExistingObjectTag/public": "yes" } } } ] } -
要检查对象有哪些标签,请在 AWS CLI 中运行 get-object-tagging 命令:
aws s3api get-object-tagging --bucket DOC-EXAMPLE-BUCKET --key exampleobject -
要向没有任何标签的对象添加标签,请运行以下 put-object-tagging 命令:
aws s3api put-object-tagging --bucket DOC-EXAMPLE-BUCKET --key exampleobject --tagging 'TagSet={Key=public,Value=yes}'**警告:**上述命令会覆盖对象拥有的所有标签。
-
要向已有标签的对象添加新标签,请运行以下 put-object-tagging 命令:
aws s3api put-object-tagging --bucket DOC-EXAMPLE-BUCKET --key exampleobject --tagging 'TagSet=[{Key=public,Value=n},{Key=exampletag1,Value=one},{Key=exampletag2,Value=two}]'**注意:**请务必包含新的对象标签以及要保留的旧标签。
-
要验证对象的标签,请再次运行 get-object-tagging 命令:
aws s3api get-object-tagging --bucket DOC-EXAMPLE-BUCKET --key exampleobject
使用存储桶策略授予对特定前缀的公共读取访问权限
**警告:**以下存储桶策略会授予对特定前缀下的所有对象的公共读取访问权限。在使用此存储桶策略之前,请确认您的用例支持此前缀内的所有可公开读取对象。以下策略不会授予前缀的列表访问权限。仅在已知对象路径时,用户才能访问该对象。如果用户尝试访问前缀中不存在的对象,则用户会收到 403 错误。
-
要授予对特定对象前缀的公共读取访问权限,请添加以下存储桶策略:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AddPerm", "Effect": "Allow", "Principal": "*", "Action": [ "s3:GetObject" ], "Resource": [ "arn:aws:s3:::DOC-EXAMPLE-BUCKET/publicprefix/*" ] } ] } -
运行 cp 命令将对象复制到具有公共读取权限的前缀:
aws s3 cp s3://DOC-EXAMPLE-BUCKET/exampleobject s3://DOC-EXAMPLE-BUCKET/publicprefix/exampleobject
**注意:**如果该对象已经具有可公开读取的前缀,则无需将该对象复制到新的前缀。
从受限网络访问公共 S3 存储桶或对象
要从受限网络访问公共 S3 存储桶或对象,您可以添加允许从特定 IP 地址范围进行访问的存储桶策略。以下示例策略允许来自 192.0.2.0/24 和 203.0.113.0/24 CIDR 范围的 GET 请求:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*", "Condition": { "IpAddress": { "aws:SourceIp": [ "192.0.2.0/24", "203.0.113.0/24" ] } } } ] }

