通过CloudFront上传至S3的文件无法访问问题求助
解决CloudFront上传S3对象后无法访问的问题
问题本质
通过CloudFront OAC上传的对象默认由CloudFront服务账号cf-host-credentials-global所有,你的AWS账号默认无该对象的访问权限,因此触发AccessDenied错误。以下是具体解决思路:
方案1:配置S3桶策略,允许你的账号访问CloudFront上传的对象
直接在桶策略中添加规则,针对CloudFront服务账号所有的对象,授予你的AWS账号访问权限:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::你的AWS账号ID:root" }, "Action": [ "s3:GetObject", "s3:DeleteObject", "s3:PutObjectAcl" ], "Resource": "arn:aws:s3:::你的存储桶名称/*", "Condition": { "StringEquals": { "s3:objectOwner": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Control" } } } ] }
配置后,你可以直接访问S3对象,甚至修改其ACL将所有权转移到自己账号下。
方案2:上传时传递bucket-owner-full-control权限(推荐)
解决x-amz-acl未签名报错的核心是让CloudFront允许并签名该请求头:
- 进入CloudFront控制台,找到对应的分发→行为设置→「缓存键和源请求」
- 在「签名的请求头」中添加
x-amz-acl(注意是签名的请求头,不是普通转发头) - 上传文件时,携带请求头
x-amz-acl: bucket-owner-full-control
这样上传的对象会自动授予桶所有者(你的AWS账号)完全控制权,对象所有者会直接显示为你的账号,后续访问无权限问题。如果使用预签名URL,需确保预签名时包含该请求头。
方案3:通过CloudFront URL直接访问对象
既然已配置OAC具备getObject权限,可直接使用CloudFront域名访问对象,而非S3原生URL:
- 确认CloudFront行为已允许
GET请求 - 检查源站配置中OAC的权限包含
s3:GetObject - 确保桶策略已授权CloudFront OAC访问所有对象(包括CloudFront上传的对象):
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::你的存储桶名称/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::你的AWS账号ID:distribution/你的CloudFront分发ID" } } } ] }
注意事项
- CloudFront配置修改后需等待5-10分钟生效,测试前确保缓存已刷新
- 预签名URL需区分CloudFront签名和S3签名机制,不要混用
- 若使用IAM用户/角色访问,需确保其权限包含对应操作(如
s3:GetObject或CloudFront访问权限)
内容的提问来源于stack exchange,提问作者Ron
相关产品推荐
相关产品推荐

