Amazon web services AWS:如何在S3 CORS配置中允许多个域?

Amazon web services AWS:如何在S3 CORS配置中允许多个域?,amazon-web-services,amazon-s3,cors,Amazon Web Services,Amazon S3,Cors,我的许多站点都依赖S3作为Cloudfront的来源,我遇到了一个问题。但是,我在允许多个域(而不是允许全局*域)方面遇到了问题 我遵循了文档(第一个配置)。并在这里和那里找到了一些其他随机的SO或论坛答案(第二个配置) 感谢您的帮助 我设置了CORS规则,这些规则看起来像以下两种: <?xml version="1.0" encoding="UTF-8"?> <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-

我的许多站点都依赖S3作为Cloudfront的来源,我遇到了一个问题。但是,我在允许多个域(而不是允许全局
*
域)方面遇到了问题

我遵循了文档(第一个配置)。并在这里和那里找到了一些其他随机的SO或论坛答案(第二个配置)

感谢您的帮助

我设置了CORS规则,这些规则看起来像以下两种:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>https://example.com</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>HEAD</AllowedMethod>
        <AllowedMethod>DELETE</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
    <CORSRule>
        <AllowedOrigin>http://example.com</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
    <CORSRule>
        <AllowedOrigin>https://staging.example.com</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
    <CORSRule>
        <AllowedOrigin>http://example.dev</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

'已被跨源资源共享策略阻止加载:请求的资源上不存在'Access Control Allow Origin'标头。因此,不允许访问源“”

跨源资源共享策略已阻止加载来自源“”的字体:“访问控制允许源”标头的值“”不等于提供的源。因此,不允许访问源“”


CloudFront根据从浏览器转发到源服务器的所有请求头缓存对象,而不仅仅是路径

对于要从缓存提供的响应,它必须是在响应前一个包含完全相同的请求头的请求时返回的

这是因为,至少在原则上,不同的头可以触发服务器的不同行为,而行为良好的缓存不能随意假设其他行为

为了提高对象的可缓存性,同时又不影响其提供正确响应的能力(即,源服务器将为给定请求返回的相同响应),CloudFront在将请求转发到源服务器之前剥离了几乎所有的请求头,并在执行缓存查找时使用请求的剥离版本

当源服务器是“自定义”(即不是S3)源服务器时,您可以选择转发到源服务器的头

但是当源服务器是S3时,您仍然可以选择,但是只有三个可以选择转发。。。而且它们都与CORS有关

[对于S3源站,]您可以将CloudFront配置为仅基于以下三个标题转发和缓存对象:
访问控制请求标题
访问控制请求方法
,以及
源站
。转发这些头允许CloudFront为支持跨源资源共享(CORS)的网站分发内容。您不能将CloudFront配置为将自定义头转发到AmazonS3

如果
Origin:
头至少没有被转发,那么S3将无法对其做出反应。启用此报头的转发意味着S3不仅会看到它,而且可能会因为bucket上的CORS配置而修改其响应,而且对于相同对象,
来源:
的每个变化都会导致不同的(正确的)响应响应由S3返回,并由CloudFront缓存以供将来匹配请求

CloudFront无法将自定义头转发到S3,因为这没有任何用途——因为S3存储静态内容,响应在其他头上不会发生变化,因此转发它们将毫无意义,并将降低缓存命中率,缓存许多(假定)不同的响应,但仅在响应带有相同标题的请求时提供服务。

Background:您的设置
  • 假设您有域A(例如
    dev.mydomain.com
    )和域B(例如
    www.mydomain.com
  • 您的CDN位于
    CDN.mydomain.com
    上,它位于CloudFront上,指向一个私有S3存储桶
  • 当您从
    www.mydomain.com
    通过
    https://cdn.mydomain.com/fonts/myfont.woff
    。(请参见如何设置,直到目前为止。)
要求(仅适用于本问题)
  • 只有当请求该文件的页面(即
    源文件
    标题)为时,您才想在
    cdn.mydomain.com/font/myfont.woff
    上访问该文件
  • junk cheap.com
    将您的字体文件加载到此页面(通过您的CDN URL)时,您不希望该文件可以访问,以节省自己的带宽/托管成本;更不用说网络钓鱼和类似的风险了
问题 默认情况下,CloudFront缓存任何传入请求的响应。这就是CDN的全部要点

但是,第一次(在失效后)请求来自某个文件的两个域中的任何一个域(例如
/font/myfont.woff
),CloudFront会将该文件的响应缓存为
{”/font/myfont.woff:“}
。因此,默认情况下,缓存密钥几乎只是路径

现在,当来自域B的请求针对同一文件时,对象的缓存响应的“允许域”是针对域a的,这种不匹配会导致CORS错误

解决方案 一个简单的解决方案是告诉CloudFront将
Origin
合并到缓存键中。因此,在上面的示例中,缓存类似于
{[“/fonts/myfont.woff”,“Origin:www.mydomain.com”]:,…}

您可以通过创建一个新的缓存策略来实现这一点,该策略采用
Origin
标题:

然后根据你的行为设置它

现在,请使分发无效并重试!它应该有用。:)


祝你好运

CloudFront发行版是否配置为将
源站
请求头列入白名单?@Michael sqlbot我不确定在哪里检查。编辑源代码不会产生任何与白名单源代码请求头相关的内容。这是一个缓存行为设置,而不是源代码设置;好吧,我
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>https://example.com</AllowedOrigin>
        <AllowedOrigin>http://example.com</AllowedOrigin>
        <AllowedOrigin>https://staging.example.com</AllowedOrigin>
        <AllowedOrigin>http://example.dev</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>HEAD</AllowedMethod>
        <AllowedMethod>DELETE</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration>