配置OAI后CloudFront带查询字符串访问S3源返回Access Denied
我之前配置CloudFront+Lambda@Edge处理图片缩放时,也碰到过一模一样的带查询字符串就Access Denied的问题!给你梳理下几个最可能的排查点和解决办法:
1. 检查CloudFront缓存行为的查询字符串转发设置
这是最常见的坑!CloudFront默认会忽略查询字符串来缓存内容,但如果你的Lambda@Edge依赖查询字符串(比如图片尺寸参数),或者需要把查询字符串传递给S3(哪怕S3本身不使用,Lambda处理时需要),必须调整缓存行为的配置:
- 进入你的CloudFront分发控制台,找到「缓存行为」标签页
- 选中对应S3源的缓存行为,点击「编辑」
- 在「查询字符串转发和缓存」选项中,选择**「转发所有查询字符串,基于所有查询字符串缓存」**(如果只需要特定参数,也可以选「转发特定查询字符串」并指定你需要的参数,比如
width、height) - 保存后等待CloudFront部署完成(通常需要5-10分钟,别着急测试)
2. 验证S3桶策略的正确性
有时候桶策略的细节写错了,哪怕看起来正确也会导致权限问题:
首先,确保你的桶策略是针对OAI授权的,正确的格式应该是这样(替换成你的OAI ARN和桶名):
{ "Version": "2008-10-17", "Id": "PolicyForCloudFrontPrivateContent", "Statement": [ { "Sid": "AllowCloudFrontOAI", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity YOUR_OAI_UNIQUE_ID" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::your-private-bucket-name/*" } ] }
重点注意:
Resource必须以/*结尾,代表授权访问桶内所有对象,只写桶ARN的话只能访问桶本身,不能访问对象- 确认OAI的ARN完全正确,你可以在CloudFront的「Origin Access Identities」页面复制到准确的ARN
- 不要有其他冲突的桶策略(比如拒绝访问的语句),同时确保S3的「公共访问设置」是开启的(阻止公共访问,这是正确的配置)
3. 检查Lambda@Edge的请求处理逻辑
如果你的Lambda函数是在Viewer Request或Origin Request阶段运行的,要确保它没有修改请求导致S3无法识别:
- 比如,函数是否错误地把查询字符串拼接到了S3对象键里?
- 是否在请求头中添加了S3不支持的字段?
- 可以去US-EAST-1区域的CloudWatch日志里查看Lambda@Edge的执行日志(所有Lambda@Edge的日志都会存在这个区域),看看转发到S3的请求路径、参数是否符合预期
4. 确认CloudFront源与OAI的关联
再检查一遍CloudFront源的配置:
- 进入CloudFront分发的「源」标签页,编辑你的S3源
- 确认「Origin Access」选项已经选中了你创建的OAI(如果是新版控制台,可能是「Origin Access Control」,确保关联正确)
- 如果之前手动修改过桶策略,也可以勾选「更新S3桶策略」让CloudFront自动生成正确的策略,避免手动写错
5. 先测试基础访问是否正常
先试试不带查询字符串的图片URL是否能正常访问:
- 如果能访问,说明OAI和桶策略本身没问题,问题就出在查询字符串转发或Lambda处理上
- 如果也报错,那先解决基础的OAI权限问题,再处理查询字符串的情况
内容的提问来源于stack exchange,提问作者ExoticChimp
相关产品推荐
相关产品推荐

