How to use a google account in your Android Application - android

I want to develop an Android Application that allows users to sign in with their Google Accounts (i think it's always an email address) instead of forcing the user to create a new one. I have 3 questions regarding this:
When the user starts the application for the first time i'll have to use the AccountManager, right? If the user has only one com.google account i'll use that one, if not, i'll ask him which one he wants to use. My question is, can i be sure that every com.google account in the AccountManager has been properly authenticated and the application can be sure that the user is who he says he is so that i don't have to ask him to choose the account every time the application launches?
The application will have a server that will store on a database what restricted content the user has unlocked, that's why it needs the Google Account, to match the foreign key of the user with the foreign key of the content to know what that user has unlocked. How do you suggest i save the Google Account in the database as the user table's primary key? I could store the email of the Google Account, but isn't there any privacy problems with that? What else can i use? I suppose there is no Facebook ID-like integer value for Google Accounts.
Do i need to use OpenID or oAuth 2.0 for any of these operations i've mentioned? I'm asking this because when the application doesn't have internet connection i want the user to still be able to access the restricted content he unlocked and previously downloaded into the phone. If i use OpenID that requires internet connection right? So the user shouldn't be able to enter the application and that's not what i want.
Thanks

Using the account manager to check which accounts are available on the phone and ask the user which account he want to use sounds like a good idea. I think it's a good idea to use OAuth 2.0 and grab the OAuth 2.0 access token for userinfo in your client application (https://www.googleapis.com/auth/userinfo.profile is probably the scope you want to use) and send this to your server when the client communicates with the server. Then using the userinfo Google API your server can use the access token to make sure the user is who he claims to be. With this api you can get hold of the user id which you can use instead of the user's email.
Getting the auth token will require internet access, but since it's only needed when you communicate with your own server you can grab the token at that time.
I'm not 100% sure if the accounts given by the AccountManager can be trusted, but it will provide you with the google accounts available on the phone and I don't know of any way of adding an account to the phone without having access to the account. If this was possible it would be a really big security issue as well so I think you can trust that the accounts given by the AccountManager are authentic.
When you get the OAuth 2.0 token on the client I suggest you use the Google Play's GoogleAuthUtil instead of the account manager if it's possible. For more details on this see: In a nutshell what's the difference from using OAuth2 request getAuthToken and getToken

Related

Is user's google password stored in Android account manager?

I am new to Android but old to Java. I have some questions before getting into my own account manager implementation. Here are the stuffs,
How google account manager works ?
I have come across couple of forums and blogs and mostly they explained how account manger is working and how to add our own. Here i have couple of questions,
How google account manager stores user's password in android ?
If they are not storing the user password in the device itself then how
they are seamlessly producing the auth tokens for the requested apps
who are using google account manager (Like maps / hangouts / ...)
References
How does Android's account manager use the stored password to retrieve an auth token?
https://developers.google.com/tasks/oauth-and-tasks-on-android
http://blog.udinic.com/2013/04/24/write-your-own-android-authenticator/
They (most probably) don't store the password but the Oauth token received from Google servers after authenticating, together with the refresh token.
All Google apps can use the same account manager to get the authentication token and talk to their backends, once this token expires, the account manager uses the refresh token to get a new token and store it in the account manager.
Storing the password is very dangerous, not just for the app, but it leaves the user's account completely vulnerable to be stolen both in the client app in the servers.

Using Google Plus Sign In on Android to authenticate a user on the server side

I'm writing an app that requires a user sign in with Google on Android and then proceeds to get data from the server (a Google App Engine instance, in this case). How could I go about making sure that the user is actually logged in instead of just calling with a user ID? Is there a way for google to check a secure token they provide on Android for authenticity? Or is there another non-google related way to do this?
Thank you for the help!
Okay, so this is actually a very simple task. You ask Google Play Services for its OAuth Token and send that. Then the server asks Google about that token and Google will give it all of the information in the scope at once using one of their multiple limitless OAuth APIs.

SSO with Google account on both website and mobile app

I'd like to use SSO (Single Sign-On) for users of my app, but I don't understand how to apply it to my case.
To summarize, we have:
a database
a website
an iPhone app / an Android App
Currently, it's possible to create an account on the site, and then use the same credentials to connect from the mobile apps. All communications between mobile apps and server work through http requests.
To put it simply, I would firstly
be able to use Google accounts to authenticate users
offering Android users to choose one of Google accounts associated with their smartphone
I found several sources of information:
Google - Using OAuth 2.0 for Login
Android - Remembering Users
Unlike what I saw in some examples, I don't need to make request to Google services like Google Calendar or Tasks, I just want to authenticate the user.
Does someone could tell me what I need to do on the website and on the mobile app. Should I store information in my database? How to ensure that after authentication, all http requests from the mobile application are really from authenticated user?
Do not hesitate to ask me to clarify some points.
Thanks in advance
As OAuth is a standard for authorization and not for authentication, it doesn't support any direct method for this. However, most providers allow you to call an endpoint that returns the id of the logged in user. Google returns the id as part of the basic profile information. This step is described in the first article you already mentioned. There are multiple libraries available to simplify this step for you.
So for identifying a user you acquire his Google user id and store/match it in your database.
To get the user's id on an Android device, there's an even more simple way. Just use Google Play Services as described in its documentation. You can find the user id in the response to the call in the last section of the documentation.
Now there's still the problem that you have to send the user id from the device to your web server and verify that this call was issued by your app. Fortunately, Google has also built a method into Google Play Services for exactly this scenario. There's a blog post by Tim Bray at the Android Developers Blog about this.

What do I need from OAuth 2.0 in this simple Android app case?

The Story: I am making an Android app that allows a user to purchase a subscription, and does not require the user to have an account or login. I want to check whether or not a user has purchased a subscription, and the Google Play Android Developer API seems to provide this service.
The Problem (TL;DR): Should I use OAuth as a "web application", "installed application", "service application", or none of the above?
The Problem: To get started with this, I am told:
Access to the Google Play Android Developer API is authenticated using
the OAuth 2.0 Web Server flow. Before you can use the API, you will
need to set up an APIs Console project, create a client ID and
generate a refresh token. -source
Fair enough. There are then setup instructions that go on to say:
On the second page, select web application and set the redirect URI
and Javascript origins.
My application does access the Internet, but it is an installed Android app, not a web application, so I don't have a "redirect URI" or "Javascript origins" to link it to. Additionally, this would require a user to log in, which I do not want and is not necessary in my case (I just want to check whether or not the user has purchased a subscription).
So if instead of a "web application" I try to create an "installed application (Android)", this still requires a user login, to be able to manage the user's resources.
I do not want this. There is a third alternative called a "service account" that does not require a user login:
A Service Account is used when you have a service that wants to handle
its "own" resources (e.g., an App Engine app that manages Compute
Engine resources), as opposed to the resources of an external user
(e.g., the standard OAuth flow). Using a Service Account the app will
be the owner of the resources... If you use a Service Account, you will only get data about the service's purchases. -source
I'm not sure if that is what I want in my case...
Finally, there is also this option:
The simplest flow is one where no end-user authorization is needed.
You still need to identify your client application using the API key. -source
This seems perfect! However, I was told initially that to use the Google Play Android Developer API I need to authenticate with OAuth 2.0, and this does not use a client ID which I was initially told that I specifically need.
There are at least 2 problems with what you are trying to achieve here:
As you would be handling the server response in your Android application, you would have something like this in your code:
if (isSubscriptionValid())
Somebody could tamper with your application's APK on his device (which is very easy) and simply replace that check with:
if (true)
The attacker would then have access to your content without ever being subscribed.
As calls to the API have to be authorized by your developer account and being personally logged in on each users device is obviously no option, you would have to go for Service Accounts, as you've already figured out correctly.
These however are only meant for server-to-server interactions, as otherwise it would require you to store your private key on everybodys device and as it is not possible to store data securely on an Android device, you wouldn't meet this requirement:
The private key must be stored and managed securely.
Google recommends you to have a backend server to do this kind of checks. So you can decide if a subscription is valid before handing over content to the client and other things:
The API is designed to be used from your backend servers as a way of securely managing subscriptions, as well as extending and integrating subscriptions with other services.
If you do not have a backend server available, you have to rely on In-app Billing Notifications.

Android AccountManager - Add New Account

I'm using the Android AccountManager to authenticate a users google account for access to Google Drive. However, I want to allow the user to access Drive accounts that are not on their phone. For example, I have a work google account that is not on my phone, but I would like to use in my app. Is there a way to allow users to authenticate accounts that are not necessarily stored in the AccountManager?
Thanks
Perhaps you could add another Google account to phone and allow user to select which account to use. If this option doesn't satisfy you and you really want to authenticate to Google Drive accounts not on phone you must then use OAuth.
If you also really, but really, want to use AccountManager facility in your app you have to make an account type that behaves like the following:
When you create a new account you open a browser widget and perform an OAuth cycle with Google Drive, then store the token in secure store
When you request a token via getAuthToken() it either releases you the stored token or triggers a token refresh cycle using OAuth
This has its security drawbacks: better perform OAuth cycle without AccountManager and store tokens in app memory

Categories

Resources