简体   繁体   中英

AWS S3 Not Sending Access-Control-Allow-Origin header when Origin header on request is present

I have an AWS S3 bucket with the following CORS policy:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
        <ExposeHeader>Access-Control-Allow-Origin</ExposeHeader>
    </CORSRule>
</CORSConfiguration>

In my app, I load a page of images from the bucket. The images appear on the page as expected. When I click on one of the images to open it in the Adobe Creative SDK, the SDK fails to load the image because it is blocked by CORS. The SDK takes the url of the image and loads it via AJAX. The SDK has an option to enable CORS and appears to be sending the proper Origin header (See screenshot), however AWS is not including the Access-Control-Allow-Origin-Header , causing the image to be blocked by CORS.

I've scoured every question on here about this subject and it seems like no one has a straight answer. There are dozens of questions on this subject that are unanswered, however in many of those cases it appears that the AJAX request isn't sending the Origin header or that the bucket isn't properly configured. In this case, neither of those are true, which is why this is not a duplicate .

As you can see in the screenshot, the request includes the Origin header, but the response does not include the Access-Control-Allow-Origin header. What I would like to know is: 1. Why isn't S3 sending the proper header if my bucket is properly configured? 2. Is it possible that when the Adobe Creative SDK requests the image via AJAX, the browser sees that the image is already cached and tried to serve the cached image (which doesn't have the Origin header) instead? 3. If #2 is the case, how can I forcibly add the Origin header to the image request? In the app, the image is the background of a div (css background-image property).

在此处输入图片说明

I created a test bucket, enabled CORS, and used your CORS rules.

Note that I am not convinced that <ExposeHeader>Access-Control-Allow-Origin</ExposeHeader> is necessary, but it should not do any harm by being present, so I've retained it.

The behavior I observe in testing is not consistent with what you are showing in your browser's request/response headers.

Using curl, I set the Origin: header to http://example.com . (Yes, that's actually what I set it to... this was not modified in the output below).

$ curl -v http://xxxxxxxxxxxx.s3.amazonaws.com/index.txt -H 'Origin: http://example.com'
* Hostname was NOT found in DNS cache
*   Trying 54.231.98.120...
* Connected to xxxxxxxxxxxx.s3.amazonaws.com (54.231.98.120) port 80 (#0)
> GET /index.txt HTTP/1.1
> User-Agent: curl/7.35.0
> Host: xxxxxxxxxxxx
> Accept: */*
> Origin: http://example.com
>
< HTTP/1.1 200 OK
< x-amz-id-2: pF39K26ii42SzxSU2Dt0KT2z7+xmfyiP4yekp9s4DCYJo0jlRwCTDg6QO6f0HMIL4H9b640zq7U=
< x-amz-request-id: 3B18A563CFF4E485
< Date: Sat, 28 May 2016 21:49:21 GMT
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET
< Access-Control-Expose-Headers: Access-Control-Allow-Origin
< Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
< Cache-Control: no-cache
< Last-Modified: Sat, 28 May 2016 21:40:57 GMT
< ETag: "cd21a8c7268dc6af728d180f9a3a81d7"
< Accept-Ranges: bytes
< Content-Type: text/plain
< Content-Length: 71
* Server AmazonS3 is not blacklisted
< Server: AmazonS3

Why is this interesting?

S3, with CORS configured and a <CORSRule> matching your request, always returns the CORS response headers and a Vary: header (which means "If you vary one of the following headers in your request, I may vary something about my response.") The headers from the above output that I am referring to, specifically, are these.

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Access-Control-Expose-Headers: Access-Control-Allow-Origin
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method

There is only one exception I can find to this, which is when there is not a matching CORS rule. To demonstrate that, I first changed my CORS configuration to <AllowedOrigin>http://example.com</AllowedOrigin> and then repeated the request. Note that the response is almost identical, except that S3 uses the exact origin in the response, and adds Access-Control-Allow-Credentials .

< Access-Control-Allow-Origin: http://example.com
< Access-Control-Allow-Methods: GET
< Access-Control-Expose-Headers: Access-Control-Allow-Origin
< Access-Control-Allow-Credentials: true
< Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method

...however, if I -- still using the more restrictive CORS rule that specifies a specific origin -- then send a request for Origin: example.org , which is an origin that is not mentioned in my CORS configuration and has no wildcard <AllowedOrigin> to match, S3 responds as though CORS was not configured at all.

< HTTP/1.1 200 OK
< x-amz-id-2: WJ0QmIZ6jTQYefFi8GjlDQkZKFHDX8/5cmejeulhG1ov3/NdoSXbsTKetYpxvXPML8aUnPNZ/ac=
< x-amz-request-id: 15A03D8B1E08A830
< Date: Sat, 28 May 2016 21:58:34 GMT
< Cache-Control: no-cache
...etc.

This takes me back to my initial conclusion that the request you've shown your browser making does not match the timing of when you configured the bucket for CORS, and may have been cached before your bucket's CORS settings were in the correct state, or before they matched those you've posted in the question.

If an Origin: header was present on that request, as the browser shows that it was, then S3 should have added the CORS response headers, whether or not the request was actually a cross-origin request.

Your next steps would be to try this with a new object at a new path that there is no possibility of being cached, or try the common browser cache-busting tactic of adding ?some-random=thing-here to the object's URL when making the request. Failing that, you should consider proving or disproving correct behavior by your bucket using a tool like curl that shows exactly what's happening in the request/response.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM