I am new to using aws and I am having some troubles. I have a set of videos that are present in multiple folders in an aws s3 bucket . I am creating an android app which would be reading the videos of bucket ,display them as list and allow the users to stream those videos.
The issue is that my app is using a non aws seperate server for authentication and thus i don't want to use aws-cognito authentication. When i tried searching for a native sdk for s3, i was pointed to aws-amplify framework and when i tried to follow the docs here , I got stuck at this step which enforces to set up the cognito authentication.
? You need to add auth (Amazon Cognito) to your project in order to add storage for user files. Do you want to add auth now?
`Yes` // <------------------------ this is for either now or later, can't say no to adding auth at all
? Do you want to use the default authentication and security configuration?
`Default configuration` //<-------------------------------------- can't say no here
? How do you want users to be able to sign in?
`Username`
? Do you want to configure advanced settings?
`No, I am done.`
? Please provide a friendly name for your resource that will be used to label this category in the project:
`S3friendlyName`
? Please provide bucket name:
`storagebucketname`
? Who should have access:
`Auth and guest users`
? What kind of access do you want for Authenticated users?
`create/update, read, delete`
? What kind of access do you want for Guest users?
`create/update, read, delete`
? Do you want to add a Lambda Trigger for your S3 Bucket?
`No`
I am not sure about this, but I believe there is a way to access some private bucket data using just an iam user access keys. So which sdk or custom code would help me access the whole private bucket for all users without needing to authenticate?
Currently, Amplify's AWSS3StoragePlugin is hardcoded to require use of Amazon Cognito for authentication/authorization.
If you would like to use IAM only, please create a feature request on the Amplify Android GitHub repository.
If you would like to auth with your own credential provider, you could federated an OpenID Connect provider with Cognito.
The nuclear option is to use the low-level AmazonS3Client, in the AWS SDK for Android. This will allow you to supply your own AWSCredentialsProvider. There are a variety of valid ways to provide credentials. Note: the AWSMobileClient is a utility for doing Cognito auth, and it is what is used in the AWSS3StoragePlugin.
If a user is supposed to be able to access the bucket without the need for authentication, you could make the objects in that bucket publicly accessible. That way you skip the extra work involved in accessing a private bucket for objects you intend to be easily accessible (no authentication).
If the objects in the bucket and the bucket itself must remain private, then you could follow this guide: "Restricting Access to Amazon S3 Content by Using an Origin Access Identity for controlling access to S3 via CloudFront. The theory is that users won't be able to access your S3 content unless is came from your OAI configured CloudFront distribution. Afterwards you can figure out a way to access your CloudFront distribution and fetch content from there using your application only.
Related
I have a bucket in Amazon S3 and I have Lambda functions that generates JSON files for this bucket. I am using the S3 files in my mobile app. Until recently, I gave public access to these S3 files for simplicity. But now I want these S3 objects to be accessible with a simple authentication. I’ve examined all AWS tutorials but couldn’t find an easy way to implement this. I don’t want to use Cognito service since my app doesn’t need authentication and since my S3 files are not user-related, they are used for app. I want these S3 objects to be accessible by http request to a url which includes simple key like this:
https://s3.eu-central-1.amazonaws.com/<bucket name>/<object name>?<key>
where key can be a combination of region, aws access key, secret access key or other values of the user that i define (I am using Retrofit to fetch json data from S3 bucket) I’ve looked at the presigned url option but an example for android-sdk doesn’t exists there, and most of the methods that can be used for this purpose are deprecated. Isn’t there an easy way for this? Or should I host my json files in other service/place?
If you say no to Cognito then you are just complicating things for yourself. This is exactly the case where you want to use Cognito. The fact that you don't require your users to authenticate and that the S3 content is not user specific doesn't mean that Cognito is not suitable in this scenario.
All you have to do is to create Cognito identity pool and choose to support unauthenticated entities. Create an IAM policy that allows reading from that specific S3 bucket and let unauthenticated users to assume that IAM role by attaching it to those unauthenticated entities.
Authentication then happens automatically during the initialization of SDK in your application. That is all that you need to do to allow access to that S3 bucket only from your application.
And you get access metrics even for unauthenticated users as a bonus. And if you later decide that you want your application to support authentication as well, then you don't need to change almost anything in your setup.
I want to create an android application and use AWS s3 as a storage service to allow the user to upload and download files. I have studied something about S3 REST service, which can help me achieve the same, after configuration of IAM Role for Bucket etc.
Now thing is, I want only the registered users of my application/ with access control configured at my web server(username/password) should be allowed to upload/download the file and not anyone with only app access should be allowed.
Look the link below as well, to have some idea about AWS S3 upload file using REST
http://www.tothenew.com/blog/file-upload-on-amazon-s3-server-via-rest-api-call/
Putting simply, in addition to that described in the link above, I just need the answer to the following questions:
1) How to allow only registered users?
2) Is it good practice to hard code AWS S3 secretKey etc in the production application.
3) Does hardcoding these values in my app could lead to a scenario where even an unregistered user of my application could be able to upload/download the file to aws s3?
All suggestions are welcome, if-if they solve part of the puzzle, as I am completely unaware of the solution
It would be very helpful...,
Thanks in advance,
For sure it is not best practice to hard code secret keys inside your codes..
Now if you want to separate the authorized and the unauthorized users one AW services that does this job and more is AWS Cognito . You can find a lot in the aws documentation https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-console.html
A few things for Cognito :
You have Amazon Cognito User Pools tha provides :
Sign-up and sign-in services.
A built-in, customizable web UI to sign in users.
Social sign-in with Facebook, Google, and Login with Amazon, as well as sign-in with SAML identity providers from your user
pool.
User directory management and user profiles.
Security features such as multi-factor authentication (MFA), checks for compromised credentials, account takeover
protection, and phone and email verification.
You have Amazon Cognito Identity Pools (Federated Identities) that provides :
Users in an Amazon Cognito user pool
Users who authenticate with external identity providers such as
Facebook, Google, or a SAML-based identity provider
Users authenticated via your own existing authentication process
This how it works in my application
Ask user register/login using aws cognito
deploy an api via api gateway that acts as proxy for S3 services
For the api , apply AWS cognito as Authorizer in api gateway
This however has a limitation on size of object
The option I have tried is use signed urls, and this is spit out by back end application upon registered users access requests.
My implementation includes below
1. Client requests signed urls using an api with a lambda implementation
2. Lambda generates signed urls and passes on the response.
3. while creating signed urls, key/id are used from a parameter store (see EC2 parameter store) secured against role and with a KEY.
I think from your use case , EC2 parameter store (instead of database) should be sufficient to securely keep secretes.
Ok, so I am new to AWS. I want to make an app that will store a small amount of user data. S3 seems to be the way to store data. Is there a way to make multiple storage spaces automatically with S3? Lets say I make an android app and people install it on their phone. Will they each automatically get an S3 storage space? how do I do that? thanks
You can create a S3 Bucket to your project with folders (depending on the architecture, can be one for customer). On this way, you will have an instance of the s3 service with all your user data.
Amazon S3 is simply an object-storage system. How you use it is totally up to you.
If you wish to store information on a per user basis, then you need to consider security in addition to how the data is stored.
If the intention is that a user can access some information that is private to them (as opposed to being publicly visible to anyone), then you first need to control access to data.
For public information, no authentication is necessary
For private information, something needs to determine what they are allowed to access, and then grant access
You should not give permanent AWS Credentials (Access Key, Secret Key) to every user. These credentials are only for your IT operations staff (you!) and for your applications.
This leaves two options:
Your central server could generate temporary access credentials using the AWS Secure Token Service, while specifying what access rights they have (eg access to a particular S3 bucket and path, or to other AWS services such as DynamoDB). OR
Generate pre-signed URLs for specific objects stored in Amazon S3.
Based upon your use-case, it seems a better fit to use pre-signed URLs. Basically, the flow is:
Your app would send a request to your central server, requesting access to an object.
The server (or rather, the app you have written that is running on a central server) verifies their identity and confirms that they should be allowed access to the object stored in Amazon S3.
The central server then generates a pre-signed URL that grants time-limited access to an object in Amazon S3 and sends the URL back to the client app
The client app then uses the URL to retrieve the data from Amazon S3
Only the app running on your central server requires AWS credentials. It then uses those credentials to generate pre-signed URLs that can be used by the client apps.
By the way, the app on the central server doesn't actually need to be running on a server. You could use AWS API Gateway to send requests to AWS Lambda functions, which can perform the logic and send back the response. This would be a serverless solution, but still with centralized logic.
An app of mine in the android playstore (let's say >1.000.000 installs) collect some anonymous statistics. I want to store and work with these statistics on an amazon EMR cluster.
Currently I use AWS Cognito for creating Unauthorized access for Uploading the data to S3/Firehose. For saving money I thought of changing this procedure to use a hardcoded IAM user, which only able to upload the data to FH/S3. I don't need the identification of each user.
What disadvantages should I expect in terms of security?
Cognito federated identities is 100% free. Switching to an IAM user won't save you money.
Per the pricing page: "Using the Federated Identities feature for authenticating users and generating unique identifiers is always free with Amazon Cognito."
I think if they somehow get access to your sourcecode they can upload data to s3/firehose . Actually I am in the same kind of dilema only I dont have an app on appstore yet but since the IAM i am using only has read access to a AWS service I dont really see issue with it. because If I am correct AWs does charge for every token refresh after 50.000 MAU if you use Cognito
I am building an Android application that will send reports to a server. These reports are plain JSON files stored on Amazon S3.
The Amazon user only has the PutObject permission on a specific S3 bucket.
The documentation states that we should use the Token Vending Machine mechanism instead of hardcoded keys within the application.
I cannot see the advantage of this method.
I get that a hacker could decompile my app to find the keys. But his only choice then is to send files to the bucket, nothing else (no file listing, no file retrieval).
If I use the anonymous TVM, the process is:
Get a token valid for 24 hours
Use this token to send files to the bucket
A hacker could also call the TVM server to request unlimited tokens and send files to my bucket. It does not seem to solve this problem.
What is the real advantage in using TVM?
You can attach different authorizations to each mobile UID, giving your finer control over what you allow people to access. You can also control how much AWS access the TVM has using policies. You can also stop it any given time. If they get your keys, you will have to disable the whole account. If you are OK with that, you probably don't need to use the TVM.