I have a static website backed by S3 bucket (b1) with a Cloudfront web distribution. A behavior on the distribution allows access to this bucket.
I have another S3 bucket (b2) with private content that is configured for access through the cloudfront URL only (configured using an S3OriginConfig and behavior).
Both b1 and b2 are configured with publicReadAccess blocked and BlockPublicAccess.BLOCK_ALL set.
I have configured a cloudfront Origin Access Identity to access the public and private s3 bucket contents and it works.
For eg: http://myapp.cloudfront.net/private_content.jpg maps to b2 since the *.jpg path pattern is configured to access the private bucket b2 that holds the jpg file and http://myapp.cloudfront.net takes me to the index page configured for the distribution.
I would like to use signed cookies as outlined in this document to prevent accessing the private content without proper authorization: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-setting-signed-cookie-custom-policy.html
Specifically, point 2. in the document:
- You develop your application to determine whether a user should have access to your content and, if so, to send three Set-Cookie headers to the viewer. (Each Set-Cookie header can contain only one name-value pair, and a CloudFront signed cookie requires three name-value pairs.) You must send the Set-Cookie headers to the viewer before the viewer requests your private content. If you set a short expiration time on the cookie, you might also want to send three more Set-Cookie headers in response to subsequent requests, so that the user continues to have access.
i.e., the requirement is to allow the viewer access to the private content only if they are authenticated.
How does one do this with a static website (mine is a Single Page App using HTML + JS files)?
Additional details:
- I use AWS cognito to authenticate users and a cognito identity pool to authorize users in my app.
- The SPA app makes backend Rest API calls to an API gateway. So, one place I could insert the Set-Cookie headers is in the first API call that is invoked. But, currently this is a different URL (not on the cloudfront distribution) and the API calls made by the webapp are CORS.
Questions:
- What is the recommended approach to ensure that only an authenticated user is able to access the private content? (Simpler and more secure suggestions welcome)
- If the Set-Cookie / cloudfront signed cookies method is the one to adopt, should I be bringing the API also under cloudfront using path routing (which would also simplify CORS)?