New user sign up using AWS Builder ID
New user sign up using AWS Builder ID is currently unavailable on re:Post. To sign up, please use the AWS Management Console instead.
为什么我在使用 Amazon S3 网站端点作为 CloudFront 分配的源时收到“403 access denied”错误?
我使用 Amazon Simple Storage Service (Amazon S3) 存储桶作为 Amazon CloudFront 分配的源。我想解决“403 access denied”错误。
解决方法
要对使用 Amazon S3 网站端点作为源的 CloudFront 分配进行故障排除,请完成以下任务。
**注意:**如果在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI。
查看存储桶中对象的加密
AWS Key Management Service (AWS KMS) 不支持匿名请求。允许匿名或公开访问的 Amazon S3 存储桶不会将此访问权限应用于使用 AWS KMS 加密的对象。从您要提供的 S3 对象中删除 AWS KMS 加密。使用 AES-256 加密您的对象,而不是 AWS KMS 加密。
确定对象是否使用 AWS KMS 加密
要检查存储桶中的对象是否使用 AWS KMS 加密,请完成以下任务:
在 Amazon S3 控制台上查看对象的属性。如果加密对话框中选择了 AWS-KMS,说明对象是使用 AWS KMS。
或者,运行 AWS CLI 来运行 head-object 命令。如果此命令的 ServerSideEncryption 返回 aws:kms,说明对象是使用 AWS KMS 加密。
更改对象的加密设置
要使用 Amazon S3 控制台更改对象的加密设置,请参阅使用 AWS KMS (SSE-KMS) 指定服务器端加密。
要使用 AWS CLI 更改对象的加密设置,确认该对象的存储桶没有将 AWS KMS 作为默认加密。如果存储桶将 AWS KMS 作为默认加密,则将加密更改为 SSE-S3。
如果存储桶没有默认加密,则运行以下命令复制并覆盖对象,然后删除对象加密:
aws s3 cp s3://DOC-EXAMPLE-BUCKET/index.html s3://DOC-EXAMPLE-BUCKET/index.html
**注意:**将 DOC-EXAMPLE-BUCKET 替换为您的存储桶名称。当您复制并覆盖对象时,该操作会删除 storage-class 和 website-redirect-location 的设置。要在新对象中保留这些设置,在复制请求中明确指定这些值。
查看您的存储桶策略
您的存储桶策略不能有阻止对 s3:GetObject 操作进行公共读取访问的拒绝语句。
如果您有显式的 s3:GetObject 允许语句,请确保没有与该语句冲突的显式拒绝语句。显式拒绝语句始终会覆盖显式允许语句。
要查看 s3:GetObject 的存储桶策略,请完成以下步骤:
- 打开 Amazon S3 控制台,然后导航到您的 S3 存储桶。
- 选择权限选项卡。
- 选择存储桶策略。
- 查看存储桶策略中是否有带 "Action": " s3:GetObject " 或 " Action": " s3:* " 的语句。
- 修改存储桶策略,删除或编辑阻止对 s3:GetObject 进行公共读取访问的语句。
例如,以下策略包含 s3:GetObject 公共访问的显式允许语句。但是,它还包含 s3:GetObject 访问的显式拒绝语句(除非请求来自特定的 Amazon Virtual Private Cloud (Amazon VPC))。修改此策略以允许 s3:GetObject 操作:
{ "Version": "2012-10-17", "Id": "PolicyForCloudFrontPrivateContent", "Statement": [ { "Sid": "Allow-OAI-Access-To-Bucket", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EAF5#########" }, "Action": "s3:GetObject", "Resource": [ "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*" ] }, { "Sid": "Allow-Public-Access-To-Bucket", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": [ "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*" ] }, { "Sid": "Access-to-specific-VPCE-only", "Effect": "Deny", "Principal": "*", "Action": "s3:GetObject", "Resource": [ "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*" ], "Condition": { "StringNotEquals": { "aws:sourceVpce": "vpce-1a2b3c4d" } } } ] }
以下策略是允许对 S3 网站端点进行只读公共访问的 Amazon S3 存储桶策略的示例:
{ "Version": "2012-10-17", "Statement": { "Sid": "AllowPublicReadOnly", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*" } }
查看存储桶和对象所有权
要让存储桶策略允许对对象进行公共读取访问,拥有该存储桶的 AWS 账户也必须拥有这些对象。
**注意:**对象所有权要求适用于存储桶策略授予的公共读取访问权限。不适用于对象的访问控制列表 (ACL) 授予的公共读取访问权限。
确认存储桶和对象属于同一个所有者
注意:您可以使用 Amazon S3 控制台来检查存储桶和对象所有者。您可以在存储桶或对象的权限选项卡上找到所有者。
要使用 AWS CLI 检查存储桶和对象所有者,运行以下命令:
运行 list-buckets 命令获取存储桶所有者的 S3 规范 ID:
aws s3api list-buckets --query Owner.ID
运行 list-objects 命令获取对象所有者的 S3 规范 ID:
aws s3api list-objects --bucket DOC-EXAMPLE-BUCKET --prefix index.html
**注意:**上述示例命令的输出显示一个对象,但您可以使用 list-objects 命令检查多个对象。如果规范 ID 不匹配,则表示存储桶和对象的所有者不同。
更新对象所有权
存储桶所有者可以使用 S3 对象所有权管理对象的所有权。默认情况下,所有新 S3 存储桶的 S3 对象所有权设置都会打开。要更新现有存储桶,请参阅在现有存储桶上设置对象所有权。
存储桶所有者的最佳做法是在所有存储桶上使用 S3 对象所有权设置。此外,通过 AWS Identity and Access Management (IAM) 角色和存储桶策略管理权限也是一种最佳做法。
要删除存储桶的 ACL 并获得存储桶中所有对象的所有权,运行 put-bucket-ownership-controls 命令:
aws s3api put-bucket-ownership-controls --bucket example-bucket --ownership-controls 'Rules=[{ObjectOwnership=BucketOwnerEnforced}]'
如果您不想关闭 S3 存储桶上的 ACL,将该对象的所有者更改为存储桶所有者。
完成以下步骤:
-
在对象所有者的账户中,运行 get-object-acl 命令来检索分配给对象的 ACL 权限:
aws s3api get-object-acl --bucket DOC-EXAMPLE-BUCKET --key object-name
**注意:**如果对象具有 bucket-owner-full-control ACL 权限,跳到步骤 3。
-
如果对象没有 bucket-owner-full-control ACL 权限,则从对象所有者的账户运行 put-object-acl 命令:
aws s3api put-object-acl --bucket DOC-EXAMPLE-BUCKET --key object-name --acl bucket-owner-full-control
-
在存储桶所有者的账户中,运行以下命令复制并覆盖对象,然后更改对象的所有者:
aws s3 cp s3://DOC-EXAMPLE-BUCKET/index.html s3://DOC-EXAMPLE-BUCKET/index.html
**注意:**将 DOC-EXAMPLE-BUCKET 替换为您的存储桶的名称。将 DOC-EXAMPLE-BUCKET 替换为您的存储桶的名称。
查看存储桶的“屏蔽公共访问权限”设置
确保未将 Amazon S3 屏蔽公共访问权限设置应用于存储桶或账户。这些设置会覆盖允许公共读取访问的权限。“Amazon S3 屏蔽公共访问权限”设置可以应用于各个存储桶或 AWS 账户。
确认存储桶中的对象可以公开访问
使用网站端点的分配支持可公开访问的内容。要确定您的 S3 存储桶中的对象是否可以公开访问,在 Web 浏览器中打开 S3 网站端点的对象 URL。或者,在 URL 上运行 curl 命令。
示例:
http://DOC-EXAMPLE-BUCKET.s3-website-us-east-1.amazonaws.com/index.html
如果 Web 浏览器或 curl 命令返回访问被拒绝错误,说明对象不可公开访问。
要允许公开读取访问,请完成以下任务之一:
- 创建一个允许对存储桶中的所有对象进行公开读取访问的存储桶策略。
- 使用 Amazon S3 控制台允许对对象进行公开读取访问。
查看“申请者付款”选项
如果启用了申请者付款,关闭此选项。“申请者付款”存储桶不允许通过网站端点进行访问。
查看自定义标头
如果您使用 referer 标头限制从 CloudFront 访问您的 S3 网站端点源,请检查您的存储桶策略。验证在 S3 存储桶策略上设置的密钥值或令牌是否与 CloudFront 源自定义标头上的值匹配。
要在存储桶策略中使用显式拒绝语句,必须有基于 referer 标头授予访问权限的允许语句。您不能仅使用显式拒绝语句来授予访问权限。
例如,当请求包含字符串 "aws:Referer":"MY_SECRET_TOKEN_CONFIGURED_ON_CLOUDFRONT_ORIGIN_CUSTOM_HEADER" 时,以下存储桶策略授予对 S3 源的访问权限。
CloudFront 源自定义标头必须具有以下配置:
- 标头:referer
- 值: MY_SECRET_TOKEN_CONFIGURED_ON_CLOUDFRONT_ORIGIN_CUSTOM_HEADER
存储桶策略示例:
{ "Version":"2012-10-17", "Id":"http referer policy example", "Statement":[ { "Sid":"Allow get requests originating from my CloudFront with referer header", "Effect":"Allow", "Principal":"*", "Action":"s3:GetObject", "Resource":"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*", "Condition":{ "StringLike":{"aws:Referer":"MY_SECRET_TOKEN_CONFIGURED_ON_CLOUDFRONT_ORIGIN_CUSTOM_HEADER"} } } ] }
**注意:**Principal 是通配符值 ("Principal":"*"),因此示例存储桶策略会授予对存储桶的公共(匿名)访问权限。由于有条件语句,请求必须包含 referer 标头,标头值必须与存储桶策略中的值匹配。如果未满足条件语句,您无法访问 S3 源。
查看您的组织的管理账户
使用您的组织在 AWS Organizations 中的管理账户来检查拒绝服务控制策略 (SCP)。查看连接到组织根、组织单位 (OU) 或直接连接到您的账户的 s3:GetObject 操作的拒绝策略。
相关信息
为什么我在使用 S3 REST API 端点作为 CloudFront 分配的源时收到“403 access denied”错误?
相关内容
- AWS 官方已更新 7 个月前
- AWS 官方已更新 4 个月前
- AWS 官方已更新 1 年前
- AWS 官方已更新 3 年前