Using Cognito and Cloudfront to control access to user files on S3

0

Hi, I'm putting together a media viewer website for myself to learn how AWS works. My first step was to host a webpage (index.html) on S3, and have this webpage allow for image/video uploads to a folder in my bucket using the AWS Javascript SDK (v2), and having the mediaviewer on the web page access these files directly through http. I have lambda functions that convert media formats appropriately, and hold metadata in DynamoDB that can be queried by the website using the javascript SDK. This all works fine.

Now, I'd like to make it a bit more secure, and support users who login, individual user directories within the buckets, and control access to the media files so users can only view their own files. So the steps I used to do this were the following:

  1. Create a user pool and identity pool in Cognito.
  2. Add a google sign in button, and enable user pool sign in with the google button... To do this, Google requires the webpage to be served via https (not http).
  3. Since S3 can't serve files via https, I put the S3 bucket behind cloudfront.
  4. Modify my bucket to have a user directory, and subdirectories for each cognito identityid. Modify the access policies so that users can only read/write to their individual subdirectory, and can only read/write to a subset of DynamoDB based on their identity ID. The webpage uses AWS Javascript SDK calls to login with cognito, upload to S3, access dynamodb. It all appears to work well, and seems to give me secure user access control.
  5. Now, the hole... I want the media viewer portion of my app to access the images/media via https:// links, and not via the javascript sdk. The way its currently configured, https access goes through cloudfront, and cloudfront has access to all the files in the S3 bucket. I'm trying to figure out how to make an https request via cloudfront (along with a cognito token), and then have cloudfront inspect the token, determine the identity ID of the user, and only serve contents for that user if he is logged in. Does this require lambda@edge or is there an easier way? I don't want to use signed urls, because I anticipate having a single user view hundreds of urls at a single time (in a gallery view), and figure generations signed urls will slow things down too much.
  6. In the future, I may want to enable sharing of files... Could I enable that by having an entry in DynamoDB for every file, and have cloudfront check if the user is allowed to view the file, before serving it? Would this be part of the lambd@edge function?

Thanks

2 Answers
0

This sample solution comes somewhat close to what you want, and could be tweaked to fit your needs: https://github.com/aws-samples/cloudfront-authorization-at-edge

Currently it misses an upload feature you need, and also it misses the feature of having users only see/edit their own files. It would not require signed URLs because it relies on good old cookies for authentication.

However I do like to point out that generating signed URLs is in fact very quick, and usable for your purpose too. I doubt it would be too slow for hundreds of URLs even. Signing an (https) S3 URL using AWS credentials is quick--this does not need to invoke any AWS service over the wire, it's a cryptographic operation that runs locally on the client (in your browser's JavaScript in this case).

I hope that helps somewhat, I realize it's not the whole story. There's a lot to your question, it's quite a full blown application you're trying to build :)

AWS
answered a year ago
  • Thanks. I did end up putting together a simple lambda@edge function that is similar to what you pointed to. I am uploading content by using presigned urls, but assume that using cookies with a lambda@edge function will be more performant for downloading content.

0

One consideration might be to look at Origin Access Control (OAC) and custom bucket polices: OAC

AWS
AWSdave
answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions