Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS: How can I allow multiple domains in an S3 CORS configuration?

I've been having an issue across many of my sites that rely on S3 as an origin for Cloudfront. However, I'm having issues with allowing multiple domains (instead of a global * allowed).

I have followed the documentation here (first config). And found a few other random SO or forum answers here and there (second config)

Any help is appreciated.

I have setup CORS Rules that look like both of the following:

<?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>

AND

<?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>

I keep getting the font origin error on all sites except https://example.com:

Font from origin 'http://CLOUDFRONTURL' has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://example.dev' is therefore not allowed access.

AND

Font from origin 'http://CLOUDFRONTURL' has been blocked from loading by Cross-Origin Resource Sharing policy: The 'Access-Control-Allow-Origin' header has a value 'https://example.com' that is not equal to the supplied origin. Origin 'http://example.dev' is therefore not allowed access.

like image 604
Rebecca Dessonville Avatar asked Jan 05 '16 15:01

Rebecca Dessonville


People also ask

How do I allow a domain in CORS?

To initiate a cross-origin request, a browser sends the request with an Origin: <domain> HTTP header, where <domain> is the domain that served the page. In response, the server sends Access-Control-Allow-Origin: <domain> , where <domain> is either a list of specific domains or a wildcard to allow all domains.

How do I enable cross-origin requests in S3 bucket?

Sign in to the AWS Management Console and open the Amazon S3 console at https://console.aws.amazon.com/s3/ . In the Buckets list, choose the name of the bucket that you want to create a bucket policy for. Choose Permissions. In the Cross-origin resource sharing (CORS) section, choose Edit.

What is cross-origin resource sharing in S3?

Cross-origin resource sharing (CORS) defines a way for client web applications that are loaded in one domain to interact with resources in a different domain. With CORS support, you can build rich client-side web applications with Amazon S3 and selectively allow cross-origin access to your Amazon S3 resources.

How do I handle CORS with html2canvas and AWS S3 images?

You have to either load your image with the crossOrigin attribute set to 'anonymous' directly in your document, or you can try useCORS h2c option. allowTaint option does just say that you don't care if it taints the canvas or not.


1 Answers

Background: Your Setup

  • Let's say you have domain A (e.g. dev.mydomain.com) and domain B (e.g. www.mydomain.com).
  • Your CDN is at cdn.mydomain.com which is on CloudFront and points to a private S3 bucket.
  • Files (e.g. /fonts/myfont.woff, which needs CORS, per MDN) are accessible when you request them from www.mydomain.com via https://cdn.mydomain.com/fonts/myfont.woff. (See my answer here on how to set it up, up to this point.)

Requirements (for this question only)

  • You want the file to be accessible on cdn.mydomain.com/fonts/myfont.woff only when the page that requests it (i.e. Origin header) is either dev.mydomain.com or www.mydomain.com.
  • You do NOT want the file to be accessible when junk-cheap.com loads your font file on this page (via your CDN URL), to save on his own bandwidth/hosting cost; not to mention phishing and such risks!

The problem

By default CloudFront caches the response for any incoming request. That's the whole point of CDN.

However, the first time (after an Invalidation) that a request comes from any of the two domains for a certain file (say /fonts/myfont.woff), CloudFront caches the response for this file as { "/fonts/myfont.woff": "<this response object with headers>"}. So the cache-key is by default almost only the path.

Now, when a request from domain B comes for the same file, the "allowed domain" of the cached response of the object is for domain A, and this mismatch results in a CORS error.

Solution

One simple solution would be telling CloudFront to incorporate Origin into the cache key. So, in the above example the cache would be like { ["/fonts/myfont.woff", "Origin: www.mydomain.com"]: <response for www.mydomain.com only>, ... }.

You can accomplish this by creating a new Cache Policy that takes in the Origin header:

enter image description here

and then set it up on your Behavior.

enter image description here

Now, invalidate the distribution and try again! It should work. :)

Good luck!

like image 198
Aidin Avatar answered Oct 06 '22 17:10

Aidin