简体   繁体   中英

AWS static website + cloudfront signed cookies

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:

  1. 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.

ie, 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:

  1. 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)
  2. 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)?

After a lot of digging and research, I found this Amazon documentation link that provides the architecture for the type of problem that I am addressing.

Kruse, O. (2019, August 16). Authorization@Edge using cookies: Protect your Amazon CloudFront content from being downloaded by unauthenticated users. Retrieved April 15, 2021, from https://aws.amazon.com/blogs/networking-and-content-delivery/authorizationedge-using-cookies-protect-your-amazon-cloudfront-content-from-being-downloaded-by-unauthenticated-users/

From the article:

The building blocks of the sample solution For the sample solution, we use the following main building blocks:

  • A private S3 bucket to host the SPA.
  • A CloudFront distribution to serve the SPA to users.
  • A Lambda@Edge function to inspect the JSON Web Tokens (JWTs) that are included in cookies in incoming requests. The function either allows a request or redirects it to authenticate, based on whether the user is already signed in.
  • A Lambda@Edge function that sets the correct cookies when a user signs in. The user's browser automatically sends these cookies in subsequent requests, which makes the sign-in persistent across requests.
  • A Cognito user pool with a hosted UI setup that allows users to complete sign-in.

The solution uses the standard “Authorization code with PCKE” OAuth2 grant, which is supported by Cognito.

If you are interested in the code sample from the above article, it isavailable here on Github .

There is another blog post from Amazon that uses a different technique of embedding a JSON Web Token (JWT) in the URL.

Tomic, A., & Worrell, C. (2018, January 29). Authorization@Edge – How to Use Lambda@Edge and JSON Web Tokens to Enhance Web Application Security. Retrieved April 15, 2021, from https://aws.amazon.com/blogs/networking-and-content-delivery/authorizationedge-how-to-use-lambdaedge-and-json-web-tokens-to-enhance-web-application-security/

The code sample for the above article is available here on Github .

In summary, you can use Lambda@Edge for authorizing private content and use either signed cookies or signed URLs as mentioned above.

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