AWS documentation has explained how to sign the cookie and set the cookie.
sign the cookie use the private key
set cookie
the browser of the user carries the cookie and tries to download the file.
CloudFront validates the cookie and responds to the request.
I have gone through several related questions.
Stackoverflow: Setting Cookies for CloudFront
Stackoverflow: share cookie between subdomain and domain
Due to security, it seems not possible to share cookies between different subdomains.
Take this real-world scenario as an example:
Web application's domain www.example.com
AWS CloudFront distribution file.example.com
How does www.example.com(web application) set a signed cookie for file.example.com(CloudFront)?
Related
I am looking into using aws cloudfront with signed cookies to serve static protected content on my webpage. AWS documentation here says we should set 3 cookies which should be passed those to our cloudfront urls (images/css/html/js/etc). Its not clear how do to this as cloudfront will be a separate domain than the one which served the page.
mywebsite.com will server a page which has links to static CDN content on mycloudfrontsubdomain.cloudfront.net and should pass the signed cookies to gain access. How do I set cookies on cloudfront.net from my own domain or is there some way AWS can do this for you. Im not great with front end web development (Im mostly backend) but my understanding is we cant set cookies for a different domain that did not serve up the current page. I would assume AWS has some endpoint we could call to have cloudfront set cookies?
Cloudfront supports alternate domain names.
For example, you can set your Cloudfront distribution to have an alternate domain name of mycloudfrontsubdomain.mywebsite.com. https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/LinkFormat.html#LinkFormat_OwnDomain
Now you can set a cookie from mywebsite.com with a domain of mywebsite.com. Cookie with that domain will also include all subdomains (so also including cloudfront). https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#attributes
I'll attach an image to illustrate what I'm looking to do:
Note: The above photo should say "Redirect to HTTPS"
To preface, this is the following is the technology stack
DNS: GoDaddy
Proxy: Cloudflare
Client: React app hosted on Heroku
Server: Flask API hosted on Heroku
The flow at least to my understanding is this:
User enters in domain.com in browser and GoDaddy forwards all traffic to Cloudflare so that the site is viewed securely
Cloudflare then forwards the traffic to where the client is hosted
Once client is loaded, it makes a request to the server to receive a CSRF token. The CSRF token is generated by a method within flask-wtf. A session is created in the server and in the response, the CSRF token is attached to the header
Here things gets weird
Since the response received on the client never had the CSRF token attached to the header and no cookie was set on the browser, I would assume that the response goes to Cloudflare before the response hits the client. As a result, the CSRF token is never received. Not sure why this is the case.. But after a bit of research, I've discovered that Cloudflare does this by default.
It seems that a work around would be to use Cloudflare Workers, but that seems only available if their DNS is being used. Ideally, I would like to stick with GoDaddy.
I was wondering if anyone else experienced this and found a different solution.
I have a AWS Cloudfront hosted webpage which takes static pages from S3 and makes calls to custom origin (ALB) for dynamic data. There is OIDC authentication enabled on ALB, so calls to custom origin (my API) passes via rules set at ALB.
In a particular case when my request to custom origin is unauthenticated I am redirected to IdP for login and after successful login I get the cookie in the response header, as this request was sent to IdP from ALB - the issued cookie has domain as ALB DNS. In order for my webpage to use this cookie I have to redirect the call to Cloudfront URL. Now the cookie was issued to ALB which has a different DNS and my Cloudfront URL has a different DNS therefore I am unable to use the cookie.
I tried to catch the cookie value but because it is issued for a different domain i am unable to catch hold, also as a part of design I feel that is wrong. Has some one faced similar type of issue.
AWS ALB OIDC sets session cookie for the same request host domain for which you configure the authentication action in the listener rules.
Also, they set a http only secure cookie, meaning you cannot access it via client side Javascript at all.
Considering this along with your setup, it seems you actually need a (tiny) backend for your web page, so that you can access the response cookie when you make the API call to the mentioned custom origin internally from this backend.
Having trouble setting a cookie (subdomain to parent) in a CloudFront configuration:
S3 bucket serving a static site with a CloudFront distribution. CNAME: example.com
API Gateway API with a custom domain: api.example.com
S3 bucket with a CloudFront distribution with CNAME: files.example.com
The web application on example.com contacts a lambda proxy GET method on api.example.com. This function, among other things, returns headers with values generated by AWS.CloudFront.Signer.getSignedCookies()
{
'Set-Cookie': `CloudFront-Expires=...; Domain=.example.com`,
'SEt-Cookie': `CloudFront-Signature=...; Domain=.example.com`,
'SET-Cookie': `CloudFront-Key-Pair-Id=...; Domain=.example.com`
}
These are being sent to the client with the response, but for some reason are not sent in GET requests to the S3 bucket on files.example.com.
I am not certain if the issue is with the cookies being set or being sent: By looking at the application tab in chrome dev tools it seems that the cookies aren't there. However, in the network tab the cookies are indeed being sent alongside requests to api.example.com (but not with requests to files.example.com).
As far as I can tell the configuration should work in terms of Domain cookie policy (the subdomain is attempting to set a cookie with a parent domain, under which is a different subdomain of the parent, that should receive the cookies). Any other immediate suspects for this sort of behaviour?
You want to use the cookie domain .example.com instead of example.com. The leading . allows subdomains to access the cookie as well.
You also need to ensure that the cookies are being forwarded to the origin in your CloudFront behavior.
We have static html pages hosted on S3, which talk to REST services hosted on EC2 (managed by Elastic Beanstalk). Because S3 and EB are different hosts, these are CORS requests. The backend server is setting the required headers to allow CORS:
if(allowOrigin){
response.setHeader("Access-Control-Allow-Origin", clientOrigin);
response.setHeader("Access-Control-Allow-Credentials", "true");
}
The problem is that the REST services use sessions, which means they send a session cookie back to the browser. But most browsers have "don't accept 3rd party cookies" by default, so this doesn't actually work. We could pass the value of the session cookie as a POST parameter, but then we'd have to re-implement session management that JEE does for us a with a simple call to request.getSession(true).
As a solution, we are hoping for some DNS wizardry that would allow us to present both S3 and EB services as if they are the same domain. So for example, do something like this:
Request: mydomain.com/somePath/to/page --> redirect to S3 bucket/somePath/to/page
Request: mydomain.com/services/path/to/service --> redirect to EB/path/to/service
So the redirect is conditional to /services/ being present as the root folder
We'd prefer to do this at the DNS level rather than from within an S3 redirect, because Amazon charges fees for every request that hits S3 (so we'd be paying twice for all hits to /services/
How can we achieve something like that? Other ideas welcome.
You can do this with CloudFront.
Create a distribution on CloudFront for your "common" domain. All requests will go through CloudFront.
Create two origins in your distribution:
One origin that will use your S3 bucket, and
One origin that will use your EB application
You can then separate these origins based on the HTTP request path using 2 behaviours.
You'll also be able to take advantage of CloudFront's ability to cache your static S3 assets.
CNAME entries, perhaps?
If I've got A.example.com as a CNAME to myhost.example1.net (or whatever), and B.example.com as a CNAME to myotherhost.example2.net (or whatever), then a web browser visiting A.example.com, if that page has a reference to B.example.com, sees them as being from A.example.com and B.example.com, regardless of where they're actually hosted.
I've got a lot of field servers where I do something like this. At the locations where I've got a static IP addresses, I've got A records for them on my primary domain range. At the locations where I don't, I've got CNAME records for them on my primary domain range, which point at Dynamic DNS records via a different provider.