Hello, I'm having a very strange issue that I can't seem to crack. I configured a private CloudFront distribution to serve content from a private S3 bucket. I am using signed cookies to grant access to the files. I am also making cross origin requests from a browser for the files, so I need to allow credentials to send the cookie. I configured a custom response headers policy to do this (I set it to set Access-Control-Allow-Credentials to true, explicitly set Access-Control-Allow-Origin to my intended domain, and set Access-Control-Allow-Methods / Access-Control-Max-Age appropriately, and it is set to origin override), and I also set up a custom cache policy to cache based on origin and access-control headers.
this cURL command is not giving the correct response:
curl -v -H "origin: https://my-subdomain.my-domain.com" -H "cookie: CloudFront-Key-Pair-Id=MyKeyPairID; CloudFront-Policy=Base64EncodedPolicy; CloudFront-Signature=SignedPolicy" https://my-other-subdomain.my-domain.com/key/to/my/private/file.txt
it yields the following:
< HTTP/1.1 200 OK
< Content-Type: application/octet-stream
< Content-Length: 576
< Connection: keep-alive
< Date: Fri, 18 Feb 2022 18:34:09 GMT
< Last-Modified: Thu, 16 Dec 2021 14:45:12 GMT
< ETag: "a50884915242f9876bea4bb633963191"
< Accept-Ranges: bytes
< Server: AmazonS3
< Vary: Origin,Access-Control-Request-Headers,Access-Control-Request-Method
< Access-Control-Allow-Origin: https://my-subdomain.my-domain.com
< Vary: Origin
< X-Cache: Hit from cloudfront
< Via: 1.1 redacted.cloudfront.net (CloudFront)
< X-Amz-Cf-Pop: EWR50-C1
< X-Amz-Cf-Id: JxMbPWHeQr0a9AAlf9PI5ksF6xGKVWL1LvpEC9XEoR_PVuVgiJ5zGA==
< Age: 626
Notice the missing Access-Control-Allow-Credentials
header.
However, this command, yields the correct response:
curl -v -H "X-some-header: nonsense" -H "origin: https://my-subdomain.my-domain.com" -H "cookie: CloudFront-Key-Pair-Id=MyKeyPairID; CloudFront-Policy=Base64EncodedPolicy; CloudFront-Signature=SignedPolicy" https://my-other-subdomain.my-domain.com/key/to/my/private/file.txt
returns:
< HTTP/1.1 200 OK
< Content-Type: application/octet-stream
< Content-Length: 576
< Connection: keep-alive
< Date: Fri, 18 Feb 2022 18:34:09 GMT
< Last-Modified: Thu, 16 Dec 2021 14:45:12 GMT
< ETag: "a50884915242f9876bea4bb633963191"
< Accept-Ranges: bytes
< Server: AmazonS3
< Vary: Origin,Access-Control-Request-Headers,Access-Control-Request-Method
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Origin: https://my-subdomain.my-domain.com
< Vary: Origin
< X-Cache: Hit from cloudfront
< Via: 1.1 redacted.cloudfront.net (CloudFront)
< X-Amz-Cf-Pop: EWR50-C1
< X-Amz-Cf-Id: pUSouCDwLH5Zu6-NBUZqKrb5kY407GLqXXtH4EK2-Th0Z9zZNb54ag==
< Age: 693
this time, with the correct Access-Control-Allow-Credentials
header. I have no idea what I might have misconfigured to cause this or why this could be happening. Any insights would be greatly appreciated, any configuration or test output needed, just let me know.
Thank you
EDIT:
After some trial and error, I've determined the origin override setting on the Response Header Policy is causing the problem. When that is set to true, it will not send the Access-Control-Allow-Credentials header unless you send some extraneous header with your request. This is an issue as it also causes unwanted preflight requests in the browser.
Turning that setting off and then configuring my S3 Bucket's CORS to look like the below fixed it:
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET",
"HEAD"
],
"AllowedOrigins": [
"https://*",
"http://*"
],
"ExposeHeaders": [
"ETag"
]
}
]
However, I'm still curious if I was misunderstanding the origin override setting and there's a way to do that correctly, or if this is a bug of some kind in CloudFront
I configured my response headers policy to set
Access-Control-Allow-Credentials
to true. As stated in my question, this works as expected if I include some random extraneous header, but does not work if I just send normal headers. That's why I can't figure this out.