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

Reb*_*lle 7 amazon-s3 amazon-web-services cors

我在许多依赖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>
Run Code Online (Sandbox Code Playgroud)

<?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>
Run Code Online (Sandbox Code Playgroud)

我一直在所有网站上得到字体来源错误,除了 https://example.com:

来自" http:// CLOUDFRONTURL "的字体已被跨源资源共享策略阻止加载:请求的资源上不存在"Access-Control-Allow-Origin"标头.因此,不允许来源" http://example.dev "访问.

来自" http:// CLOUDFRONTURL "的字体已被跨源资源共享策略阻止加载:"Access-Control-Allow-Origin"标头的值" https://example.com "不相等到提供的原产地.因此,不允许来源" http://example.dev "访问.

Aid*_*din 10

背景:您的设置

  • 假设您有域 A(例如dev.mydomain.com)和域 B(例如www.mydomain.com)。
  • 您的 CDN 位于cdn.mydomain.comCloudFront 上并指向私有 S3 存储桶。
  • 当您从via请求文件时(例如,根据 MDN/fonts/myfont.woff需要 CORS ),可以访问它们。(到目前为止,请参阅我的回答,了解如何设置它。)www.mydomain.comhttps://cdn.mydomain.com/fonts/myfont.woff

要求(仅针对此问题)

  • cdn.mydomain.com/fonts/myfont.woff您希望仅当请求该文件的页面(即Origin标头)为 或 dev.mydomain.com 才能访问该文件www.mydomain.com
  • 希望在在此页面上加载字体文件时访问该文件junk-cheap.com(通过您的 CDN URL),以节省自己的带宽/托管成本;更不用说网络钓鱼和此类风险了!

问题

默认情况下,CloudFront 会缓存任何传入请求的响应。这就是 CDN 的全部意义。

但是,第一次(在失效之后)来自两个域中的任何一个对某个文件(例如/fonts/myfont.woff)的请求时,CloudFront 会将此文件的响应缓存为{ "/fonts/myfont.woff": "<this response object with headers>"}. 所以默认情况下,缓存键几乎只是路径。

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

解决方案

一种简单的解决方案是告诉 CloudFront 将其合并Origin到缓存密钥中。因此,在上面的示例中,缓存将类似于{ ["/fonts/myfont.woff", "Origin: www.mydomain.com"]: <response for www.mydomain.com only>, ... }.

您可以通过创建一个包含标头的新缓存策略来实现此目的Origin

在此输入图像描述

然后在你的Behavior上设置它。

在此输入图像描述

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

祝你好运!


Mic*_*bot 6

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

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

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

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

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

但是当源站是S3的时候,你还是有选择的,但是可以选择转发的只有三个……而且都是CORS相关的。

[随着S3的起源,]你可以配置CloudFront的转发和缓存仅基于三个头的对象:Access-Control-Request-HeadersAccess-Control-Request-Method,和Origin。转发这些标头允许 CloudFront 为启用跨源资源共享 (CORS) 的网站分发内容。您无法将 CloudFront 配置为将自定义标头转发到 Amazon S3。

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/header-caching.html#header-caching-web

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

CloudFront 无法将自定义标头转发到 S3,因为这没有任何用处——因为 S3 存储静态内容,响应不会因其他标头而异,因此转发它们将毫无意义,并且会降低缓存命中率,许多(据说)不同的响应被缓存,但仅用于响应伴随相同标头的请求。

  • 我理解解释,但不清楚(也许因为英语不是我的母语)这里的结论是什么 1)结论是,是的,cloudfront 不可能有多个 Origin ,即使 S3 存储桶允许2)这是可能的,但必须做一些特定的操作 (2认同)