配置双源的CloudFront访问公开S3 Bucket时出现Access Denied问题
解决CloudFront访问S3源时的AccessDenied问题
我之前也碰到过类似的路径匹配坑,结合你的配置来看,核心问题应该是CloudFront转发请求到S3时的路径处理不符合预期——虽然你的S3桶本身权限和文件访问都没问题,但CloudFront的行为规则没配置到位。下面是具体的排查和修复步骤:
1. 修正CloudFront行为的路径转发规则
你设置了S3源匹配myapp/*,但CloudFront默认会把包含前缀的完整请求路径发给S3。也就是说,当你访问https://xxxx.cloudfront.net/myapp/1.js时,CloudFront实际请求的是s3://myapp-bucket/myapp/1.js——但你的S3桶里只有根目录下的1.js,并没有myapp/子目录下的对应文件,自然就触发了AccessDenied。
修复方法很直接:
- 进入CloudFront控制台,找到你的分发,编辑对应的
myapp/*行为 - 在路径设置区域,勾选「转发到源时移除前缀」,然后把前缀填成
myapp/ - 保存更改后,CloudFront就会把请求路径转换成
1.js去S3桶里查找,和你直接访问S3的路径完全一致
2. 确认S3源的访问权限配置
虽然你的桶策略已经开放了公开读,但还是要检查两个细节:
- 如果你给CloudFront配置了OAI(源访问身份),那你的桶策略应该授权这个OAI访问,而不是给所有
AWS:*开权限。不过你说直接访问S3正常,大概率没开OAI,但还是确认下:- 如果用了OAI,把桶策略里的
Principal替换成你的CloudFront OAI的ARN,比如"Principal": {"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXX"} - 同时要确保S3的「阻止公开访问」设置里,没有勾选“阻止存储桶策略公开访问”,否则你的桶策略会被强制覆盖失效
- 如果用了OAI,把桶策略里的
3. 验证行为优先级和缓存
- 确认
myapp/*的行为优先级是0(比*的优先级高),这样请求myapp/1.js才会优先匹配到S3源,而不是被错误转发到ELB - 测试前先手动失效CloudFront的缓存(路径填
/myapp/1.js),避免旧的缓存规则干扰测试结果
快速排查技巧
用curl -v https://xxxx.cloudfront.net/myapp/1.js查看响应头,重点关注这两个字段:
- 如果看到
X-Cache: Error from cloudfront,基本可以确定是路径转发的问题 - 如果响应头里出现ELB相关的标识,说明行为优先级没设置对,请求被误转到ELB了
内容的提问来源于stack exchange,提问作者Darshan Chaudhary
相关产品推荐
相关产品推荐

