AWS S3如何配置权限仅允许自有域名访问存储桶内图片资源
核心问题定位
你当前配置失效、权限异常的原因有4个:
- Resource配置错误:策略中写的
arn:aws:s3:::my-bucket仅代表存储桶本身,不包含桶内的图片等对象,要让规则作用到文件,资源必须配置为arn:aws:s3:::my-bucket/*。这是你Deny规则完全不生效、关闭公共访问阻止后所有来源都能打开图片的核心原因——规则根本没有约束到具体文件。 - 权限范围配置错误:
s3:*覆盖所有S3操作(包括修改桶配置、删除文件、上传文件等高危操作),公开访问场景仅需要给匿名用户开放s3:GetObject(读取对象)权限即可。 - 规则逻辑错误:IAM策略默认是隐式Deny,只要正确配置允许规则的范围,不需要额外写全局Deny规则。你写的全局Referer校验Deny规则会拦截所有不带目标Referer的请求,包括你在AWS控制台操作桶的请求(控制台请求Referer是aws.amazon.com,不是你的域名),这也是你连根用户都失去管理权限的原因。
- Block Public Access逻辑理解错误:该开关是S3的顶层防护,优先级高于所有桶策略和ACL配置,只要开启针对公共桶策略的拦截项,所有给匿名用户(Principal为*)的授权都会被直接拦截,不管桶策略怎么写都不会生效。
Block Public Access 配置要求
如果要使用Referer防盗链的桶策略,你需要调整Block Public Access设置:
- 关闭Block public access to buckets and objects granted through new public bucket policies
- 关闭Block public and cross-account access to buckets and objects through any public bucket policies
- 剩下两个针对ACL的公共访问阻止选项可以保持开启,避免误通过ACL开放公开权限。
注意:Referer字段由客户端浏览器控制,可以被随意篡改,这种方案只能拦截普通用户直接新开标签页打开图片、低阶爬虫盗链,无法实现高强度的访问控制。如果需要更高的安全性,应该搭配CloudFront使用签名URL/签名Cookie做鉴权。
正确可用的桶策略
以下策略既可以实现Referer防盗链,也不会影响你对存储桶的管理权限:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowAdminFullAccess", "Effect": "Allow", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/*" ], "Condition": { "StringEquals": { "aws:PrincipalAccount": "替换为你的12位AWS账号ID" } } }, { "Sid": "AllowRefererGetObject", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::my-bucket/*", "Condition": { "StringLike": { "aws:Referer": [ "https://www.example.com/*", "https://example.com/*" ] } } } ] }
配置说明:
- 第一条规则会无条件放行你账号下所有授权身份(根用户、IAM用户、角色)的所有操作,不会再出现丢失管理权限的问题
- 第二条规则仅允许来自你指定域名的请求读取桶内对象,直接在地址栏访问图片时,浏览器不会携带目标域名的Referer,会被默认拦截
- 请将配置中的桶名、账号ID、域名替换为你实际的参数,如果你的站点支持http访问,也需要把http开头的域名加入Referer列表
其他说明
- CORS配置仅控制浏览器跨域AJAX请求的访问权限,和图片src加载、直接地址栏访问的权限控制无关,不要混淆两者的作用。
- 配置完成后可以先开浏览器隐私窗口测试:直接访问图片URL应该返回403,从你的站点页面内嵌加载图片应该正常显示。

内容的提问来源于stack exchange,提问作者daprezjer
相关产品推荐
相关产品推荐

