How to access DynamonDB of Amazon Web Service from Android SDK without through Token Vending Machine?
There are a few options, including one that was introduced by AWS very recently.
One option is to use Web identity Federation. Here, you put code in your app to have users log in with an identity provider like Login with Amazon, Google, or Facebook login, and as a result, your application gets temporary AWS credentials, when can be restricted to particular items or attributes in your DynamoDB tables using Fine-grained access control.
The new option is a service called Amazon Cognito, which is a simple user identity and data synchronization service geared toward mobile apps. I encourage you to take a look at this service and watch the short intro video to see if it suits your needs. Even if you don't use the data synchronization component, you can still use the user identity management component, and have the same fine-grained access control capabilities as the other solution, but with additional login and user management capabilities like unauthenticated guest access.
Related
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.
My main question is what is the typical way mobile apps authenticate users? I know that AmazonCognito is used to sync userdata once you receive a token, but that token is simply a set of access rules, right? Which has nothing to do with a particular user (just the fact that they are an authenticated user in general).
But before even that, there needs to be a way to authenticate a username/pass that the user signed up for so that you can retrieve the token. In almost all of the documentation, they use Facebook/Google/etc as examples of third party providers, and there IS an example of setting up your own 3rd party provider, but this all requires your own backend to service that. C
onsidering that there may be many users trying to user the app and authenticate, does it not seem like a bad idea to set up a backend somewhere else? And is there a way to integrate this part into AWS as well so that there is no custom backend work? How is this typically done?
Site node: I'm using Android SDK at the moment.
Thanks :)
AWS Cognito has two different purposes. One is to synchronize data as you described in your question.
The other one is to help to manage user identities and create the glue between external Identity Providers (your own, Facebook, Google or Amazon) and AWS.
Here is the workflow at high level. Details are available at http://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/cognito-auth.html
Using AWS Console, create a Cognito Identity Pool
Associate two IAM Policies to your Cognito Identity Pool. One for the unauthenticated users and one for authenticated users. Best practices is to grant least privileges to both category of users. The AWS Console will help you to go through these steps and will propose reasonable default values.
In your code, initialize your CognitoCredentialsProvider object as this
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
myActivity.getContext(), // get the context for the current activity
"AWS_ACCOUNT_ID",
"COGNITO_IDENTITY_POOL",
"arn:aws:iam::AWS_ACCOUNT_ID:role/UNAUTHENTICATED_ROLE",
"arn:aws:iam::AWS_ACCOUNT_ID:role/AUTHENTICATED_ROLE",
Regions.US_EAST_1
);
In your code, proceed as usual to authenticate your users (using your own provider or Facebook, Google or Amazon)
When you will receive the token issued by the Identity Provider, associate it to Cognito. The Cognito SDK will transparently trade this token for a temporary AWS Access Key, Secret Key that service clients can use.
Give the credentials provider to your service client object, such as
AmazonDynamoDB client = new AmazonDynamoDBClient(credentialsProvider);
This approach allows you to avoid to deploy your own backend as broker to AWS services. Most service calls can be made directly from the mobile app, allowing a good level of scalability at a low cost.
Backend of your own is only required to offload some computing task of your mobile devices or if you want to implement your own Identity provider and make it interact with Cognito (see detailed workflow at http://mobile.awsblog.com/post/Tx2FL1QAPDE0UAH/Understanding-Amazon-Cognito-Authentication-Part-2-Developer-Authenticated-Ident)
I am quite new to android and recently started building an application which requires
Registration using a google id.
Continuous interaction with a back-end server.
For the registration , i was wondering if it is possible to have a python webapp on Google App Engine which has the OAUTH2 authentication .
This page if opened in a webview should return the token to GAE (please correct me if i am wrong here , because i am not sure the token won't just go directly to the app).
Then again on the backend i generate a token(newly generated) and update the user tables with this new token and pass this onwards to the application.
Every subsequent request made by the app will be referenced using this token.
Is this feasible or is there a better standard way to do it (i do not want to use the login info already stored in the phone) ?
Also , how can i get information from a google account(name,email) like Facebook has access to the graph is there a google counterpart ?
As far as I understand, you implement your Android app using WebView. This means that the app interacts with the server the same way as the built-in Android web-browser. As a result you don't need to add anything special to your Android app with regards to authentication.
Built-in Users service
In GAE, you get out-of-the-box support for three different types of authentication where all of them are designed in a way that your app doesn't store user credentials but rely on user authentication from identity providers:
Google Accounts (e.g. jonny#gmail.com)
Google Apps Domain (e.g. jonny#mydomain.com hosted in Google Apps)
or Federated Login (a.k.a. OpenID, e.g. Google, Yahoo!), which is going to be replaced by Login with oAuth2 (OpenID Connect)
All three types allow your app only access to very basic information of the user. Enough to match a returning user of your GAE app to their data, and an email address or unique ID, but that's it. For more, see below (oAuth2 consumer).
In appengine console, you can select your preferred authentication type in page Administration > Application Settings.
Whatever of these types you use, in your Python code you can use GAE's Users service which will deal with the authentication of your users. Basically, you just write something like:
from google.appengine.api import users
user = users.get_current_user()
if not user:
# The user is not signed in.
else:
print "Hello, %s!" % user.nickname()
On development server, you will be prompted with a dummy login page for requests where you require login or admin login. In live environment they will be replaced by GAE with real login page flow. There are also articles linked in the docs with HTML/JS examples if you want to show custom login pages to your users, for example User Experience summary for Federated Login
oAuth2 for authentication and authorization with Google
Regarding oAuth2, with the built-in authentication it is rather easy to integrate the builtin oAuth service, so your GAE app becomes a service provider, i.e. a user of your GAE app can share data with any 3rd party app or website through some simple API. You also can have your GAE app consume data that your users have stored somewhere else (e.g. Google) and they want to share with your GAE app (consumer). If you are especially interested into accessing user data in Google services, there is this good overview.
Custom user management
Finally, you could implement your own authentication mechanism, rather than relying (and depending) on GAE features. For example you can implement your custom user management based on webapp2. This means that you have control of the user-accounts and credentials, but aside of eventual security risks the disadvantage is that it can be really hard and tricky to integrate services and APIs like Google Cloud Endpoints.
I've seen AccountManager in the Android SDK and that it is used for storing account information. Thus, I cannot find any general discussion of what it is intended for. Does anyone know of any helpful discussions of what the intention behind AccountManager is and what it buys you? Any opinions of what type of Accounts this is suitable for? Would this be where you'd put your user's account information for a general web service?
This question is a bit old, but I think it is still of good interest.
AccountManager, SyncAdapter and ContentProvidergo together.
You cannot have a SyncAdapter without an Account in the AccountManager.
You cannot have a SyncAdapterwithout a ContentProvider.
But you can:
use the ContentProvider without the others.
use the AccountManager without the others (but you cannot use an AccountManager without a SyncAdapter before Android 2.2 / Froyo API 8)
With AccountManager / SyncAdapter / ContentProvider:
AccountManager gives users a central point (Settings > Accounts) to define their credentials
Android decides when synchronization can be done via SyncAdapter. This can be good to optimize battery (no sync is done when network is down, for instance)
ContentProvider is a convenient way to share data across applications
Note: there are other methods of inter-process communication on Android.
ContentProvider schedules the database access in a background thread The AsyncQueryHanlder helps to query the ContentProvider in a background thread, preventing Application Not Responsive (ANR) errors while not requiring you to explicitly handle threading.
ContentProvider ties into ContentResolver's observer: this means it is easy to notify views when content is changed
Bottom line: the framework AccountManager / SyncAdapter / ContentProvider helps if you want to synchronize data from a web resource. Fake/Dumb implementations are required on API 7. Also
If you only want to store data, you should consider a simpler mechanism for data storage
If you only need to fetch an only resource, you can use an AsyncTaskLoader
If you want to load images asynchronously, you can use specialized libraries like Square Picasso
If you only want to execute some code at a given time, you can consider a Service / Alarm
only available from API >= 7 (this doesn't matter anymore)
Finally, if you use a SyncAdapter, seriously consider Firebase Cloud Messaging (previously Google Cloud Messaging) aka "push notifications" to have fresher updates and optimized battery usage.
The AccountManager class is integrated with your phone accounts. So if you follow all the guides and get it working correctly you'll see your accounts under the menu "Settings->accounts and sync". From there you can customize them or even delete them. Furthermore the accountManager has a cache of the authentication tickets for your accounts.
This can be used also if you don't plan to synchronize your account (as far as I know).
If you don't want your accounts to appear under that menu you shouldn't use the AccountManager and store the accounts data elsewhere (maybe in the shared preferences) http://developer.android.com/guide/topics/data/data-storage.html
From http://www.c99.org/2010/01/23/writing-an-android-sync-provider-part-1/:
The first piece of the puzzle is
called an Account Authenticator, which
defines how the user’s account will
appear in the “Accounts & Sync”
settings. Implementing an Account
Authenticator requires 3 pieces: a
service that returns a subclass of
AbstractAccountAuthenticator from the
onBind method, an activity to prompt
the user to enter their credentials,
and an xml file describing how your
account should look when displayed to
the user. You’ll also need to add the
android.permission.AUTHENTICATE_ACCOUNTS
permission to your
AndroidManifest.xml.
The AccountManager is good for the following reasons:
First is to store multiple account names with different levels of access to the app’s features under a single account type. For example, in a video streaming app, one may have two account names: one with demo access to a limited number of videos and the other with full-month access to all videos. This is not the main reason for using Accounts, however, since you can easily manage that in your app without the need for this fancy-looking Accounts thing… .
The other advantage of using Accounts is to get rid of the traditional authorization with username and password each time an authorized feature is requested by the user, because the authentication takes place in the background and the user is asked for their password only in certain condition, which I will get to it later.
Using the Accounts feature in android also removes the need for defining one’s own account type. You have probably come across the apps using Google accounts for authorization, which saves the hassle of making a new account and remembering its credentials for the user.
Accounts can be added independently through Settings → Accounts
Cross-platform user authorization can be easily managed using Accounts. For example, the client can access protected material at the same time in their android device and PC without the need for recurrent logins.
From the security point of view, using the same password in every request to the server allows for possible eavesdropping in non-secure connections. Password encryption is not sufficient here to prevent password theft.
Finally, an important reason for using the Accounts feature in android is to separate the two parties involved in any business dependent on Accounts, so called authenticator and resource owner, without compromising the client (user)’s credentials. The terms may seem rather vague, but don’t give up until you read the following paragraph … 😉
Let me elaborate on the latter with an example of a video streaming app. Company A is the holder of a video streaming business in contract with Company B to provide its certain members with premium streaming services. Company B employs a username and password method for recognizing its user. For Company A to recognize the premium members of B, one way would be to get the list of them from B and utilize similar username/password matching mechanism. This way, the authenticator and resource owner are the same (Company A). Apart from the users obligation to remember a second password, it is very likely that they set the same password as their Company B’s profile for using the services from A. This is obviously not favorable.
To allay the above shortcomings, OAuth was introduced. As an open standard for authorization, in the example above, OAuth demands that the authorization be done by Company B (authenticator) by issuing some token called Access Token for the eligible users (third party) and then providing Company A (resource owner) with the token. So no token means no eligibility.
I have elaborated more on this and more on AccountManager on my website here.
I am developing an Android application which requires users to register and log on to a website and then use that registration information in an Android app. Should I be using oauth or openid or is there something better to make it not a requirement that I develop a single-use authentication system?
OpenID
If you're just looking to authenticate a user in your android app without exchanging data between your application and user data stored & managed by a third party service provider (like google,flickr,facebook,....), then OpenID might be the better option for you.
There is a java based library that should work on the Android platform called openid4java.
OAuth
OAuth, although part of the workflow involves authenticating against an OAuth service provider, is more focussed on the authorization part, as it is to a large degree unaware of the underlying authentication mechanism.
If you want your application to act on the users behalf (to fetch user data stored at a third party that supports oauth), then OAuth is an interesting option. OAuth is not capable of acquiring the identity of the user, it merely acts as an authorization mechanism for an already identified user.
Signpost is a java based library that works on Android.
OpenID Connect
For early adopters, another interesting solution on the horizon is Open ID connect, that combines the best of the 2 worlds.
Take a look at the following posts for more background info.
What's the difference between OpenID and OAuth?
http://softwareas.com/oauth-openid-youre-barking-up-the-wrong-tree-if-you-think-theyre-the-same-thing
http://thenextweb.com/socialmedia/2010/11/04/facebook-connect-oauth-and-openid-the-differences-and-the-future/
And of course the specs :
http://openid.net/
http://oauth.net/