AccountManager vs AIDL vs ContentProvider are use to share data with other app. but which is the better for sharing authentication details with other app like google does.
I prefer AccountManager .
This class provides access to a centralized registry of the user's
online accounts. The user enters credentials (username and password)
once per account, granting applications access to online resources
with "one-click" approval.
Different online services have different ways of handling accounts and
authentication, so the account manager uses pluggable authenticator
modules for different account types. Authenticators (which may be
written by third parties) handle the actual details of validating
account credentials and storing account information. For example,
Google, Facebook, and Microsoft Exchange each have their own
authenticator.
The Android Account Manager is basically an API available to Android developers that makes use of the OAuth protocol. Developers have to jump through some hoops to get their app to display in Accounts & Sync, but the first step is adding the AUTHENTICATE_ACCOUNTS permission to the manifest file for the app.
Content Provider is the mechanism used to expose many of a device's data resources for retrieval and update: Contacts, media store, bookmarks, phone-call log, and so on. It’s hard to find an interesting Android app that doesn’t either use or implement (or both) a Content Provider.
Please read
What should I use Android AccountManager for ?
When to use a Content Provider
When to use an aidl based service?
Related
I'm trying to work out the best solution for a particular situation I'm in, and am having trouble working out the best option. It's a tricky setup, so might be a fun challenge for you Android experts! Here's my situation:
We have two Android apps already on the Play Store, and are working on another right now.
The two released apps are signed with the same keystore, but do not currently have a sharedUserId set in their manifest files.
The two released apps store a user's oAuth token in SharedPrefs, some product/content data in an SQLite DB, and some audio/video content in external storage (using getExternalFilesDir).
The apps are all separate oAuth clients/applications of our server (i.e. they all use different client ID and secret keys).
Our server is setup to only allow one oAuth token per oAuth application (i.e. Android app). e.g. if a user logs in to app A on one device, then logs into app A on another device, the first device's token will be invalidated and the app will receive a 401.
We've successfully implemented a single sign-on system on iOS by enabling shared keychain between the apps. If an app detects that another app in the group has a valid oAuth token, it can send that to our server and exchange it for a valid token for that app.
In the iOS version, we wanted to ensure that the apps didn't need to know about the existence of the other apps using hardcoded values per-app (e.g. if we release a new app in the future, other apps don't need to be updated to share/receive tokens with it), so we created an entry in the keychain containing an array of bundle IDs that had valid tokens, that all apps could access. When an app successfully logs in or exchanges a token, they add their own bundle ID to that array. Any newly installed app could find a bundle ID from that array, and use that it as a key for loading the token details for that app, which it would then exchange for its own fresh token.
We want the token exchange to be automatic and not require input from the user.
I hope that all makes sense!!! Please let me know if not.
I'm now trying to work out the best method for storing oAuth tokens (plus some additional data such as email address to go with it) on Android so that other apps owned by our account can access them in order to exchange for a fresh token.
I've looked into using the following, but am unsure of the best route:
SharedPreferences along with sharedUserId
AccountManager (https://developer.android.com/reference/android/accounts/AccountManager.html)
Android Keychain (https://developer.android.com/reference/android/security/KeyChain.html)
ContentProviders
The problem with option 1. seems to be that setting the sharedUserId after first release will lose access to all of the data (see http://java-hamster.blogspot.jp/2010/05/androids-shareduserid.html). This is not a nice thing for our users.
Option 2. (AccountManager) could be a good option, but if we want to store the tokens separately (per-app), but want any other apps we make to access their tokens, I'm not sure how we'd do that.
Option 3... is it possible to do what we need with Keychain?
If I understand correctly, option 4 would need each app to have its own ContentProvider? I'm not sure how that would work for our requirements.
If anyone has gone through this kind of situation and could share some insights and recommendations, I'd really appreciate it!
ContentProvider is probably your best best. I won't be able to provide the whole code for you to do this, but this is generally how I see it working:
Each app creates a content provider that exposes their own API token;
Each app tries to acquire and query (sequentially until successful) all the other content providers before requesting a login;
If app X is able to acquire and retrieve the token from app Y (via Y's content provider), then store it in app X and use it;
Side notes:
This is very sensitive information, so you should enforce security. Your content providers should only be accessed by other apps signed with the same key, they should have only read permissions and you should create your own custom permission as well.
The content provider does not need to access an sqlite database. It can access whatever your using to store the token (which I hope is stored in a secure way, but I'll leave that to your own judgment)
Useful links:
How to create a custom content provider
How to secure your content provider
Example of content provider that retrieves data from shared preferences;
AccountManager is meant to solve the exact problem that your are commenting. Here is a good tutorial to work with it:
http://blog.udinic.com/2013/04/24/write-your-own-android-authenticator/
Just be sure that you sign all your apps with the same keystore, because this is the only thing that might complicate things (a lot).
Using preferences will lead you into a problem as all that you store in the main thread is not guaranteed to be there in a Service (like a SyncAdapter). There used to be a trick for this in the form of flag (MULTI_SERVICE) but was deprecated in api 23.
ContentProvider is of course possible (its too generic) but AccountManager will help you to cover the corner cases related from refreshing tokens and other interesting stuff.
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.
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'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.