S3的私有内容CORS问题

时间:2018-12-19 16:37:48

标签: amazon-web-services amazon-s3 cors

问题

我已经摸索了很长时间,试图浏览围绕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>

在这里也没有运气,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标头。

Cloudfront发行问题

根据this的回答,默认情况下,cloudfront不会将标头转发到S3。我已采取步骤转发所有标头,包括Access-Control-Allow-MethodsAccess-Control-Allow-Origin

此外,另一个人建议cloudfront偶尔会有奇怪的缓存问题。我还向图像添加了一个随机查询字符串,结果相同。

两者都还是403。

在整个设置过程中,我有点不知所措,并且正在考虑其他选项,例如后端可以自己处理授权的代理服务器。尽管允许所有来源不是我的最终目标,但它应该在此时起作用。有人有什么想法吗?

2 个答案:

答案 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/*"
                ]
            }
        }
    }
]

}