S3 的私有内容 CORS 问题
Posted
技术标签:
【中文标题】S3 的私有内容 CORS 问题【英文标题】:Private Content CORS issues with S3 【发布时间】:2019-05-20 04:48:18 【问题描述】:问题
很长一段时间以来,我一直在摸不着头脑,试图浏览围绕 AWS 生态系统的许多 3 字母首字母缩写词服务。
我要做的是在网站上显示内容(pdf、图像、视频),其中该内容只能在网站上显示给经过身份验证的用户,不能可下载或公开访问。
我的问题是,无论我尝试什么,在从前端请求图像内容时都会出现 403 错误,除非允许对存储桶进行完全公开访问。。
应用程序的架构是一个前端 JS 应用程序,通过托管在 S3 上的 CloudFront 分发提供服务。这与托管在 EC2 上的后端进行通信。
到目前为止我已经尝试过什么
CORS 配置
关于该主题的documentation 似乎暗示只是创建 CORS 规则以允许从我的网站访问存储桶中的对象。
我为存储桶创建了一个类似于以下内容的 CORS 策略,它应该允许访问存储桶中的对象:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>http://*.websitename.com</AllowedOrigin>
<AllowedOrigin>https://*.websitename.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
这里不走运,403 错误。为了测试它是否可能不是 CORS 配置,我打开了 CORS 策略以尝试允许公共 CORS 访问存储桶,如下所示:
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
这里也没有运气,*** 上的其他人提到 AllowedOrigin: *
存在一点记录问题,并尝试以下操作:
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>http://*</AllowedOrigin>
<AllowedOrigin>https://*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
一位用户在 *** 上指出,直接链接的内容默认不发送 Origin
标头,这意味着 S3 会将其解释为内部请求并发送 403 禁止错误。解决方法是在图片标签中添加crossorigin="anonymous"
。
将此属性添加到img
标签后,确认标头发送正确。它在请求标头中发送正确的Origin: mywebsitename.com
,我什至收到了正确的response
标头,包括我的网站在内的允许来源。
Cloudfront 分发问题
根据this 的回答,Cloudfront 默认情况下不会将标头转发到 S3。我已经采取了转发所有标头的步骤,包括Access-Control-Allow-Methods
和Access-Control-Allow-Origin
。
此外,另一个人建议 cloudfront 偶尔会出现奇怪的缓存问题。我还向图像添加了一个随机查询字符串,结果相同。
两者之后,仍然是 403。
我对整个设置有点摸不着头脑,正在考虑其他选项,例如后端的代理服务器,我自己处理授权。虽然允许所有起源不是我的最终目标,但它应该在这一点上起作用。有人有什么想法吗?
【问题讨论】:
只是一个问题:您是否从 Cloudfront 添加了对存储桶的访问权限?如此处所述:aws.amazon.com/de/premiumsupport/knowledge-center/… 【参考方案1】:我找到了可提供我需要的解决方案的存储桶策略。
例如:
"Version": "2012-10-17",
"Id": "http referer policy example",
"Statement": [
"Sid": "Allow get requests originating from www.example.com and example.com.",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::url/*",
"Condition":
"StringLike":
"aws:Referer": [
"https://example.com/*",
"https://www.example.com/*"
]
]
【讨论】:
【参考方案2】:content can only be displayed on the website to authenticated users and not be downloaded or publicly accessible
您的 CF 或 S3 将所有内容视为未经身份验证。将您的 S3 配置为允许来自 CF 的所有请求,并尝试使用 Lambda@Edge 检查身份验证并允许或拒绝请求。另一种选择是对 S3 使用签名 URL,但这涉及更多工作。
【讨论】:
以上是关于S3 的私有内容 CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章
ViewerJS、S3 和 CORS - 从不同的 S3 存储桶/域加载资源
没有 S3 存储桶的 AWS Cloudfront CORS 标头