Can Google Account auth tokens be shared between services? - android

I'd like to use users' Google accounts to authenticate (not authorize) them from a web application and to uniquely identify their Android device[s] that run a companion app. Communications between the platforms will be done via Google Cloud Messaging.
The web service can obtain an auth token when users authenticate their Google accounts via the Google OAuth 2.0 implementation. The Android app obtains an auth token via the AccountManager.
Is the token returned by each platform identical such that it can be used as a reliable ID? If not, am I forced to ask permission to view the user's email address just to accomplish this?
I don't want to access the user's email address for identification--it's an extra permission and responsibility to secure it.

All tokens are unique -- that way, you can withdraw authentication for one device/platform while retaining it for another. Utilize the user_id, which is intended exactly to associate the same user across platforms.

The auth token expires every hour so it will never be a good id.
user_id is what you want

Related

How can I securely store user credentials for my app

I have an Android app that allows users to interact with a third-party service via their API. This API makes use of Basic Authentication, so I need the user's username and password for every API call. Ideally I don't want to store the user's credentials locally as this is very insecure. I don't know much about authentication but this is what I think my ideal solution would be:
The user provides their credentials to this service once for verification
Once verified, I send the user's credentials to a backend service to store them, which gives me an auth token. I store this token locally (is encryption important here?)
Whenever I want to make future calls to this service, I use this auth token to talk to the backend service, which provides me with the user's username/password for Basic Authentication to make API calls
Is this a good solution? If so, are there backend services in place that I can use to facilitate this process? I've looked at Firebase Authentication but I don't know if it fills my needs as I'm trying to store credentials for a third-party service, not specifically for my app. I've heard of Auth0 which may be what I'm looking for but appears to be overkill for a small app like mine.
You can easily use Firebase Auth and get all the functionality you need while keeping your users secure. It provides the features you need:
Firebase supports password authentication and properly stores hashed/salted password credentials according the industry standards. This would be one API to createUserWithEmailAndPassword or signInWithEmailAndPassword.
Firebase provides a mechanism to verify email addresses. It is also one API: user.sendEmailVerification()
On sign in, Firebase Auth returns an ID token (user.getIdToken()) which you can use to identify your users in all authenticated requests. They also provide an Admin SDK to parse and verify that token (auth.verifyIdToken(idToken)). A refresh token is also provided to continuously refresh ID tokens on expiration. This means the sessions are indefinite and the user should not need to sign in again on the device.
The ID token provides additional user data like email_verified which you can use to ensure the user is verified. The ID token is a JWT which can't be compromised without the Firebase Auth backend private key.

How to link user account among google actions, mobile app, backend server and firebase auth?

Not sure if this is the right place for this question. This is not necessary 100% coding problem but it is not not a coding problem either. Anyway, here is
The Story: I want to create a shopping system. The user can use the website or the mobile application or the google assistant to get product information and make purchases from this shopping system. The problem I am facing is how can I associate the user among these 3 clients. More specifically for the google assistant/actions.
Things I have done:
Using firebase auth for authenticate and login users onto the website or the mobile applications. After the user is authenticated and a firebase access token is available for the website or mobile app to use. The website or the mobile app can send the firebase access token to the backend server, and the backend server can verify this accessToken through firebase admin sdk. Everything is working as expected until I want to introduce the google actions/assistant into play.
For google assistant/actions: I followed this and this for logging the user into the google actions app. At this point, I am able to get user basic profile information if the user logged into the google actions app using their google account.
The Problems:
After I get the user profile such as user id, email, etc, from the google action login, then I query the database on the backend server and if I find a user with this id or email, then this is a valid and authenticated user, and I will allow the user to make purchases through google assistant. Is this approach safe and sound for identifying the user on google actions/assistant?
Assume the above approach is safe and sound, what can I do if the user account was created using other email account instead of google account? i.e. The user initially registered either on the website or mobile application using a non-google email or other Oauth2(fb, twitter, etc) through the firebase auth. In this case, my backend database won't have google account information for the user, and if the user log onto my google actions app using a google account, I will have no way to identify this user in the existing user database.
Is there a way to authenticate/login the user onto the google action app through firebase auth and obtain a firebase access token on the google actions' fulfillment backend server? If there is a way to do this, I suppose the previous problem will not exist because I will be able to use this firbase token to verify the user no matter if the user account was created using google account or other email accounts or other Oauth2 providers.
If all of the above failed, is dumping firebase auth and creating my Oauth 2 service an option and is it going to be the only backup plan available for me?
Some answers to your questions:
If IDs or Email matches - does this identify the user?
Well, yes and no.
If the IDs match, then you have verified that the Google ID for the account that logged in matches the Google account you have on record. Great! This is secure and you can trust it.
If the email matches... well... a much lower degree of confidence. While Google does do opt-in checking, this still seems like you're taking a risk. Email addresses do change over time.
What if they authenticated via some other means?
Did I summarize that question correctly?
I guess I'm not sure how you would handle this in any other case. If they're logging into your Assistant app using a different account (not email, account) than they used for the web... they want the two to be different?
And they can log into your Action using a different Google account than the one they used to setup their device. There are flows that encourage them to use the same one, but they don't have to, and you can fall back to those other flows if you don't have an account on record for the one they use by default.
Can't I just use Firebase Auth?
Well... no and yes.
No, there is no way to just tell the Assistant to hand you a Firebase auth token instead of the token it wants to hand you.
However, you can use Firebase Auth if you're willing to setup your own OAuth2 server. The link to the StackOverflow question above was just trying to work around having to setup an OAuth2 server yourself. If you set one up you can have them login using Firebase Sign-In, generate the token and store it against their Firebase ID, and issue that token to the Assistant client. When you get that token back, you can easily associate it back to the Firebase ID.
BUT You need to do that work. Neither Firebase nor the Assistant will do it for you.
(A missed opportunity for Firebase and Google Cloud, imho. But...)
You've already seen the page for how to build a minimal OAuth2 server.
Should I just dump Firebase Auth?
There is no need to. You can use Firebase Auth in conjunction with setting up your own OAuth2 server. It is a great base for it! I, personally, use Firebase Auth and Firebase Sign-In (and Firebase Hosting and Firebase Functions) as the basis for my OAuth2 implementation.

Secure Google Plus Sign-in into Web App via Android App

I'm developing an Android app and I want users to sign-in to my app using Google+ Sign-In.
At the moment, I pass the user's name which I get from Google+ within a PHP login script. The script loads a new session with the user's ID.
Currently, the site is highly insecure: anyone who knows another user's username can potentially login as them.
What is a secure way to do this?
How do I authorize a user against my server?
It looks like to me, Google+ was purely a social networking API...
Google+ Sign-In uses OAuth 2.0 - which means the user does not authenticate directly with your server. Instead they authenticate with Google and obtain a token signed by Google. Your app gets that token (from Google Play services on Android) and can pass it to your servers as proof that the user authenticated with Google. You then associate the users Google+ ID with a new or existing user ID on your own servers. So whenever a user can prove that they authenticated with Google for a specific Google+ user ID, you treat them as authenticated on your own server.
To implement, you have a few options depending on how you architect your system:
When you simply want to authenticate your user to your own servers: On an Android device your user is very often already authenticated with Google because they have a Google account in the account manager. Your app can take advantage of this and obtain a token for a user in the account manager without them having to type any passwords. After the user clicks 'Sign in with Google' in your app, you can fetch an ID token for them using GoogleAuthUtils.getToken() and pass it to your server. Your server, after verifying the Google signature, can then safely associate the users session with the appropriate user account and permissions (ie. treat the session as authenticated). The process of getting the token and verifying it is discussed by Tim Bray here and by Ian Barber here.
If you want to authenticate the user to your own servers and make Google+ API calls from your servers: Then you should take a look at the server side flow documentation on developers.google.com. This takes the same approach as option one, but in addition, when the users signs in for the very first time the Android app requests an authorization code instead of an ID token. This can be exchanged by the server for an access token and refresh token - which, in turn, can be used by your server to make API calls on behalf of the user, for example, by using the PHP client library.
If you want to authenticate the user to your own servers, but also make Google API calls from the Android device: Then you should use the PlusClient provided by Google Play services to make Google API calls in addition to the steps you take to authenticate the user with your own server.
You probably want to make Google API calls in your client or on your server so that you can pre-populate your registration form with data from the users Google+ profile, for example.
Google Plus uses OAuth 2.0
https://developers.google.com/+/api/oauth
It has auth token. You can use auth token to access Google Plus from Android or server.
On server you can verify token by accessing Google with that token.

How can an application server associate Google accounts to a user's device?

I want users to be able to enter data from a web server and/or native PC app and transfer it to their chosen Android device in much the same way that Google Play's install on device works.
I'd like to use the user's Google account authentication to establish a link between the application server and the user's Android device that registered with GCM.
I couldn't find any mention of how to handle this kind of authentication in the Google Cloud messaging API documentation, but did find this unanswered question in the GCM forums.
I'd like to authenticate users from a web application via the his or her Google account. Similarly, the Android application would somehow obtain a handle on the same Google Account, which would be sent to the web application server once at same time as initial GCM registration.
Then when the user uses the web application, the server provides a list of devices the user has already registered to the server, so that the user can be prompted about which Android device he or she would like to send data to.
How can I accomplish this on the web server as well as on the device?
What information can I use after authenticating with the Google account to establish a link between the two logins?
You should use the user_id that is returned from the Google account server after registration to uniquely identify each user. Email addresses shouldn't be used for a number of reasons:
Accessing email addresses may require additional permissions from the user and dissuade users from using your service/app because of trust issues.
Adds liability for securing database of users' email addresses
Users may change their email addresses in Google accounts but cannot change their user IDs.
Users can associate one email address with more than one user ID, so it is not necessarily unique.
The following sequence diagram shows the initial registration from client Android app:
The next diagram shows what happens when a client wants to access his device from a browser:
Note that although not shown, the client Android app can now communicate back to the client browser if needed via the application server.
The user_id you get from the device when you register with GCM should be the same as the user_id you get with your OAuth token for your app. Just store the OAuth token and Registration ID in your user repository, associating both with the user_id.

How can my server authenticate Android users with their Google accounts?

I'm building an Android app as part of a client/server architecture, where my server will provide a service to the Android client. The server will not communicate with any Google server, but will need to authenticate the user via their gmail account. That is, the server needs to be sure that the http(s) requests coming from the phone are indeed from the person with that specific gmail account.
I was looking into Android's C2DM framework, which I can certainly use for passing service-related data back and forth, but how can I use Google account authentication between an Android phone and a third-party (non-Google) server?
Will Oath2.0 work for this, or is Oath2.0 only used for direct authentication between the phone and Google's services?
You didn't mention which language code you're going to use in your server.
The easier way to use C2DM is inside Google App Engine which comes with native support for Android integrations with C2DM.
If that's not the case ( EX: youre using php in your own server ) I would take a look to AccountManager which can provides you the auth token ( the app-user must allow it ).
When registering a new device to your C2DM server you'll need the device to communicate also the token so you'll be able to know if the user is really owner of that gmail account through a connection between your server and Google Servers.
:)
I think you must have got the answer to your query by now. But I still would to answer this question to assist other users who are interested in achieving something like this.
So to use google account access token to authenticate and authorize your app user against your own services you have to follow following steps.
Create a project in Google Cloud Console with two components (Create components by clicking on "APIs $ Auth >Credetials" option on left pane ). First component will be your web component (e.g. web-services) and second component is your android application.
Try to get access token by querying account manager in android app by executing GoogleAuthUtil.getToken() method by passing the current context, email id(queried using account manager) and scope as ("audience:server:client_id:").
Where is the "Client ID" parameter of the web component available under the project created on Google Cloud Console.
The method will return you the ID token encoded as JSON web token or JWT.
This ID token everything that a app would require to authenticate user on server.
The ID token consists of following parameters
iss: always accounts.google.com
aud: the client ID of the web component of the project
azp: the client ID of the Android app component of project
email: the email which identifies the user requesting the token, along with some other fields.
Pass this token to your web component (e.g. web services) over https(mandatory) where the web component and Android component client id's are already stored.
After decoding the received JWT ID token on server, check if "aud" parameter of the token and stored web component client id are equal and hence authenticate the user.
User identity can be fetched by reading the email parameter of JWT ID token which specifies the email id provided to access the Id token in android application while executing GoogleAuthUtil.getToken() method.
Note : The ID token on android can only be fetched by executing GoogleAuthUtil.getToken() if it is the same application singed by same certificate specified while creating android component under the project on Google Cloud Console.
More information can be found on "https://developers.google.com/accounts/docs/CrossClientAuth"

Categories

Resources