Let's say I want to store some files for each user which is using my website on s3. Later I want authenticate each request to s3 to make sure that user has access to the files she is requesting. I guess this can't be done using presigned URLs or signed cookies(using cloud front). So which Amazon service should I use for that? What is the simplest way to achieve this?
Lets saying I'm authenticating users using jwt and its possible to recognize wheather a user has access to a file or not by the filename and content of the jwt.
I'm sorry that I don't have enough reputation to comment so I'll post an answer here.
One solution is:
AWS Cognito (Federated Identities)
S3 (one bucket)
S3 bucket policies allow you to restrict access to "user folders" equivalent here to "identity" by the prefix like yourbucket/<cognito_identity_id>/* Each user on your webpage will have its own federated identity.
When you create and configure the identity pool in AWS define a custom authentication provider and authenticate users "by the developer" in your backend.
Also, associate the authenticated identities to one IAM Role with access to the S3 bucket where you will keep the data. The bucket policy will take care of only allowing each user to their files and not to others. (See referenced links for policy example and more)
Amazon S3: Allows Amazon Cognito Users to Access Objects in Their Bucket
Access to User level folders using Amazon S3 and Cognito
Developer Authenticated Identities (Identity Pools)
Related
I made a dashboard where users can upload files. I want to make it so that users can only have access to S3 urls that are files that they uploaded. How can I achieve this?
The users are application based, meaning they are, in my case, Django users.
Thanks! Anything helps!!
As this is entirely application based there are a few steps you could take to try and mitigate against accidental exposure.
Firstly organise your S3 folder structure in a way that uses prefixes for usernames, this way from a hierarchical point of view you can limit the scope of where users objects are stored. By prefix I mean the key might look like this users/$USERNAME/file.txt where $USERNAME is actually the users username.
You could enhance this in in your application by expanding to use Cognito, with a seperate user for every user you have created. When the user logs into your application you could also have the login occur via the Cognito user (this can be done programmatically).
With a successful login you'll be provided temporary credentials for IAM, all users can be assigned to a Cognito group which can have an IAM role attached. When you login it will assume this role, which allows some special properties to be supported in IAM.
By using ${cognito-identity.amazonaws.com:sub} you can actually limit the IAM permissions to only access that prefix of the S3 bucket. This moves responsibility from your application to Cognito and IAM.
More information about this is available in: Amazon S3: Allows Amazon Cognito Users to Access Objects in Their Bucket.
I have a cognito user pool which is connected to google as identity providers (so that I can log in with a gmail account). I also have a private bucket s3 with files (). How can I use my lambda function, using the token returned by Cognito (AcessToken, IdToken) to get access to my s3 bucket which is not public?
I just want to use my cognito to access my private files on s3.
Something like the Cognito Authorizer for lambda functions just for s3 bucket.
You can use Signed URLs to achieve this.
Basically, after your user successfully authenticated by Cognito, your Lambda function will generate s3 pre-signed url for object requested and reply it back.
Example from AWS Documentation
Also take a look at this AWS forum thread
The only way that i know to do this is give the role access to the cognito user
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_s3_cognito-bucket.html
I'm starting with AWS. I want to create a flat-file website hosted in S3 with a restricted area protected by a password. I'm doing user authentication with Amazon Cognito.
For the restriction of unlogged users there is a problem, I can't just serve flat files and check for the JWT token with javascript, because the user can easily disable javascript or mess with it and still read the file.
How to protect/restrict access in this case? Does Amazon S3 provide any restriction or redirection of access for unlogged cognito users?
If you are using AWS Cognito Federated identities, you can define two distinguish IAM roles to assume for authenticated users and unauthenticated users.
In each of these role policies, you can define which part of S3 is allowed to access and the actions you can perform.
Note: If you are currently using Cognito Userpools, you can connect it with Cognito Federated Identities to implement this feature.
I am developing a web application with two mobile(Android & iOs) based applications of the same. Currently the files uploaded are open to all, which in terms means that anyone with the direct image link can open it using a web browser.
How can I protect or limit the file access to the users of my mobile applications or web application ?
NB: As a beginner, I am not sure about the configuration details to be provided along with question, If I need to give more details on my s3 config. please specify it, I can add it to the s question to make the question more meaningful, so sorry for the inconvenience.
I think an easier approach than pre-signed urls would be to use Amazon Cognito to provide access to AWS resources to your trusted applications, even to unauthenticated users.
To do this you would create an Identity Pool for your application (just need one pool for all 3 of your clients) and then configure it so that when a client provides a valid Identity Pool Id they can assume an IAM role with permissions to access AWS resources.
Then you control what S3 bucket permissions the IAM role they assume would have - you could allow unauthenticated users access to read the S3 objects, or force them to create accounts to be able to read/write to S3 buckets (this is very easy with Cognito - users can sign up with facebook, gmail, their own email, etc.)
There's a step-by-step guide here for setting up an identity pool with Cognito, and then allowing unauthenticated users to assume an IAM role that can access the contents of an S3 bucket
The above causes the same set of permissions for all guest user accounts - that have assumed an IAM role through Amazon Cognito by identifying themselves as part of an identity pool.
edit: I should point out that if you authenticate via Cognito, you'll need to access the S3 bucket through the S3 Transfer Manager from the AWS SDK
I need to allow users to access files on S3 with a specific prefix -- ie username1 -- that I can't change, so I can't just use the ${cognito-identity.amazonaws.com:sub} as the prefix. My S3 bucket is already populated with content under specific prefixes - so a user logs into my app, and is then allowed to access one of those specific prefixes
Currently set up on AWS to allows users to authenticate in a Cognito role using Firebase and developer authenticated identities. Each user account (email/password) has an associated S3 prefix that they must be able to access. Some users will share this prefix (two users accessing S3-bucket/username1 for example). A user should not be able to list or access any other prefix except their associated prefix.
I'm not quite sure what the best way to go about accomplishing this -- just with Cognito roles or using a database and lambda function + api endpoint, bucket/user policies or ACLs. Is there a simple way that I'm missing?
Pretty new to AWS, any help will be greatly appreciated!
tl;dr: How to only allow a user to access files on S3 with a specific prefix, that is NOT the ${cognito-identity.amazonaws.com:sub} variable?
As mentioned in comments, Amazon Cognito does not directly support your use case today. You can implement something like the following to achieve your goals:
Use Cognito to authenticate your users as normal. The Cognito identities would have permissions to invoke an API Gateway endpoint.
Your API (running in a Lambda) uses the Cognito identity id (provided in the context) to lookup the mapping of Cognito identity to your custom S3 prefix.
Your API uses STS to generate temporary credentials to access that prefix, returning them to the client.
The client uses those credentials to make a request directly to S3.