如何配置AWS S3实现公开路径可访问、私有路径仅签名URL可访问
S3+CloudFront公私路径权限配置解决方案
问题根源
你当前配置的核心问题出在CloudFront行为规则和桶策略的配合逻辑上:
- Sid 2直接给CloudFront OAI开放了private路径的
s3:GetObject权限,而你现有的CloudFront只有默认的无签名校验的行为,因此所有发往CloudFront的private路径请求,都会被CloudFront用OAI权限直接从S3获取内容返回,相当于private路径也被公开了。 - 你删除Sid2之后,OAI没有private路径的访问权限,哪怕是合法签名请求,也没办法从S3拿到内容,所以会报权限不足。
修复步骤
第一步:拆分CloudFront行为配置
你当前只有一个默认(*)行为,需要新增两条行为(优先级按路径精准度从高到低设置):- 路径模式为
public/*的行为:设置为允许所有用户访问,无需签名校验,关联你的S3源站即可,保证public路径资源所有人可直接访问 - 路径模式为
private/*的行为:必须启用「受限制的访问」,开启签名URL/签名Cookie校验,优先级设置高于public路径规则。开启后只有带有效CloudFront签名的请求才会被转发到S3源站,无签名的请求会直接被CloudFront返回403。
- 路径模式为
第二步:调整S3存储桶策略(可选优化)
你现有的桶策略不需要删除Sid2,只要保证OAI有private路径的访问权限即可,可优化为以下版本(去掉不必要的private路径本身的权限,只保留对象访问权限,同时保留public路径的配置):
注意:public路径下的资源必须打上{ "Version": "2008-10-17", "Id": "PolicyForCloudFrontPrivateContent", "Statement": [ { "Sid": "AllowPublicPathAccessViaOAI", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXX" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::myproject-development/public/*", "Condition": { "StringEquals": { "s3:ExistingObjectTag/public": "yes" } } }, { "Sid": "AllowPrivatePathAccessViaVerifiedOAIRequest", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXX" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::myproject-development/private/*" } ] }public:yes的对象标签才能正常访问,如果你不需要标签校验,可以直接删除Condition块。第三步:确认签名URL生成逻辑
确保你的PHP API生成的是CloudFront签名URL,而非S3原生签名URL,你的S3开启了全量公共访问拦截,S3原生签名URL无法正常使用。
验证方式
- 配置生效后直接访问
https://<你的CloudFront域名>/private/<测试资源路径>,应该返回403错误 - 用PHP生成的CloudFront签名URL访问同一个private路径资源,可正常获取内容
- public路径资源可直接无签名访问
内容的提问来源于stack exchange,提问作者z0mbieKale
相关产品推荐
相关产品推荐

