我已经摸索了很长时间,试图浏览围绕AWS生态系统的许多3个字母的缩写服务。
我要做的是在网站上显示内容(pdf,图像,视频),其中内容只能在已认证的用户上显示在网站上,而不能在不显示的情况下显示在网站上。下载或公开访问。
我的问题是,无论我怎么做,除非允许完全公开访问存储桶,否则从前端请求图像内容时都会出现403错误。
该应用程序的体系结构是一个前端JS应用程序,可通过S3上托管的CloudFront发行版提供服务。这与EC2上托管的后端进行通信。
该主题的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>
在这里也没有运气,stackoverflow上的其他人提到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>
一个用户在stackoverflow上指出,默认情况下,直接链接的内容不会发送Origin
头,这意味着S3然后将其解释为内部请求并发送403禁止的错误。解决方案是在图像标签中添加crossorigin="anonymous"
。
将此属性添加到img
标记后,确认标头已正确发送。它在请求标头中发送了正确的Origin: mywebsitename.com
标头,我什至收到了包括我的网站在内的允许来源的正确response
标头。
根据this的回答,默认情况下,cloudfront不会将标头转发到S3。我已采取步骤转发所有标头,包括Access-Control-Allow-Methods
和Access-Control-Allow-Origin
。
此外,另一个人建议cloudfront偶尔会有奇怪的缓存问题。我还向图像添加了一个随机查询字符串,结果相同。
两者都还是403。
在整个设置过程中,我有点不知所措,并且正在考虑其他选项,例如后端可以自己处理授权的代理服务器。尽管允许所有来源不是我的最终目标,但它应该在此时起作用。有人有什么想法吗?
答案 0 :(得分:0)
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,但这需要更多的工作。
答案 1 :(得分:0)
我找到了存储桶策略来提供所需的解决方案。
例如:
{
"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/*"
]
}
}
}
]
}