How do I set cloudfront signed cookies when its a different domain? - amazon-web-services

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

Related

How does web application share signed cookie with AWS Cloudfront?

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

Signed cookies between subdomains on CloudFront

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.

Route53 is changing my Cloudfront site to "not secure"

The entirety of my web application is contained within various AWS services and is working properly with Cloudfront.
When I go to abcxxxx.cloudfront.net my site works as expected and is secured with https.
When I try and use my own custom domain with Route53 and setting www.mywebsite.com and mywebsite.com as aliases, it is no longer secure.
My alias target for each is the proper Cloudfront domain.
I don't know if the following has to do with my problem but when I try to go to mywebsite.com it says:
"this site cannot be reached"
but when I go to www.mywebsite.com it redirects to https with the "https" crossed out in red and displays "not secure".
Cloudfront also has the proper CNAMES.
How do I properly configure Route53 to work like my Cloudfront domain?
Mark B answered the question. Don't use Cloudfront's default SSL Certificate. Go to Certificate Manager and request a new one and use that one in Cloudfront. My site then worked exactly as expected

DNS magic (AWS Route53) to expose S3 and EBeanStalk as single domain (to avoid CORS)

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.

Supporting HTTPS URL redirection with a single CloudFront distribution

I have a domain formulagrid.com.
I am using AWS S3 to host it as a static website. My problem was that I wanted to redirect the www subdomain to the bare domain like so:
https://www.formulagrid.com -> https://formulagrid.com
http://www.formulagrid.com -> https://formulagrid.com
Amazon provides URL redirecting from S3 bucket to S3 bucket if both are setup for static website hosting.
So what I had to do was set up two buckets:
formulagrid.com - actual website
www.formulagrid.com - exists solely to redirect to the actual website
This works perfectly fine if you're operating only over HTTP, but S3 has absolutely no support for HTTPS.
The way that one can use HTTPS to connect to an S3 static website is by setting up a CloudFront distribution in front of an S3 bucket. CloudFront, however, while it does provide HTTPS, mainly exists to function as a CDN.
Initially, I had a single CloudFront distribution setup in front of the S3 bucket holding the actual site. Everything seemed operational: the site was distributed over the CDN, it had HTTPS, and HTTP redirected to HTTPS.
There was one exception.
https://www.formulagrid.com was a completely broken page
After trying to find the source of the error for a while, I realized it's because it wasn't going through the CDN, and trying to access S3 over HTTPS doesn't work.
Finally, what I ended up having to do was provision another distribution to sit in front of the www S3 bucket so it was accessible over HTTPS. This is where my concerns come in because, like I mentioned earlier, CloudFront's main purpose is to be a CDN.
It doesn't make any sense to me to have a CDN sit in front of a url that just redirects to another. Also it brings up the question of whether I would be double charged for every request that hits the www subdomain because it'd hit the other CloudFront distribution after being redirected.
This is frustrating because I'm trying to do a "serverless" architecture using Lambda, and having to provision an EC2 instance just to do url rewriting isn't something I want to do unless it's my last resort.
The solution would be trivial if Amazon offered any form of URL rewriting or if CloudFront itself did redirecting, but neither of these exist as far as I know (let me know if they do).
I'm new to AWS so I'm hoping someone with more experience can point me in the right direction.
You're thinking too narrowly -- there's nothing wrong with this setup.
The solution would be trivial if Amazon offered any form of URL rewriting
They do -- the empty bucket.
S3 has absolutely no support for HTTPS.
Not for web site hosted buckets, no... but CloudFront does.
CloudFront is not just a CDN. It's also an SSL offloader, Host: header rewriter, path prepender, geolocator, georestrictor, secure content gateway, http to https redirector, error page customizer, root page substituter, web application firewall, origin header injector, dynamic content gzipper, path-based multi-origin http request router, viewer platform identifier, DDoS mitigator, zone apex alias target... so don't get too hung up on "CDN" or on the fact that you're stacking one service in front of another -- CloudFront was designed, in large part, to complement S3. They each specialize in certain facets of storage and delivery.
So, you did it right... most of it, anyway... Create a bucket, configure it for web site hosting, set it to redirect all requests to another site (the non-www) and put a CloudFront distribution in front of it -- using the web site endpoint URL for with bucket in CloudFront, not the one from the drop-down list -- configured with high TTLs so that CloudFront will send a minimal number of requests to S3 then put your (free!) SSL certificate from Amazon Certificate Manager. HTTPS alternate domain routing: solved. No servers, no troubleshooting, and cheap. The only charges are the usage -- there is no background recurring charge as there would be with servers.
Extra credit: configure the redirecting CloudFront distribution for the cheapest rate tier. Redirects from more expensive locations will either be routed to a cheaper edge location or -- at CloudFront's option -- may be served out of a higher cost location but billed at the lower rate.
Note that most of the time, CloudFront should serve the redirects from S3 from it's cache... and when you configure a bucket to redirect all requests to another hostname, the redirect is a 301 permanent redirect -- which browsers are supposed to cache, themselves.