Effective OAuth for Google APIs from Android phone - android

I am trying to get Authorization for Google Buzz,Contacts from an Android application.
The flow is similar to this.
The user chooses if he wants to use Buzz.
Using OAuth/Client Auth, we need to get a one-time authorization code.
This code would be used by a web service to periodically read Buzz feeds.
Now, the problem is how do I obtain the authorization code (Not temporary token) from the Android App and send it to the webservice.
I could use the normal OAuth2.0 and use my webservice as the redirect URL to obtain the code. But in that case how can I let the webservice know that the code pertains to which user?
Can I pass extra information with the OAuth dance?

I strongly recommend using OAuth 2. The flow is much better for the end user and it's a lot easier to implement something like this. Additionally, it uses bearer tokens, which means that you can maintain your refresh token server side where it's actually secure and only ship access tokens to the Android when they're needed.
The downside of this approach is that effectively every time your app loads it needs to phone home to get the latest access token. But once it has that access token, it can make whatever API calls it needs to, directly to the Buzz and Contacts APIs.
However, to do this, you don't pass extra information with the OAuth dance. Instead, your Android app needs to have already securely identified which user is signed in with your app, and then make sure the server only ever sends back access tokens associated with the authenticated user. If it doesn't have an up-to-date access token for that user, it would need to make a request out to Google's authorization server to get the latest access token, and then pass it up to the client. So there's certainly a strong potential for some latency there, because that generally needs to be a synchronous call, but that's usually a small price to pay for the advantages OAuth 2 gives you over OAuth 1.

Related

Authentication, android, private API, how to glue the parts together?

Let's say I have this application developed for Android which needs to use a Facebook (or Twitter or Google or all of them) based authentication so it can access this private API I've developed with nodejs' Express for example (could be any other platform too). I've read this answer here that gave me a hint on how to associate my authentication model with my user model (and another one here that made me realize those two parts are different), Facebook authenticates and I use some information they provide to create an "identity" for this user, but what exactly is this information that will create a link between the user and the identity? no abstract terms please, do I need to use and send either the access token or the Facebook user id? or would I just send the access token and let the server get the user id?
Regarding new requests after this user has been authenticated, I've read about API keys of some sort, which are basically some random strings that I should add to my identities (or users? this part confuses me) entities, and they should be securely stored in the mobile device as a mechanism to authenticate further requests, but how do I securely get this random string to the device in the first place? am I misunderstanding the way API keys work? are Facebook authentication and API keys mutually exclusive? if so, what would I use for further requests just using a provider for my authentication? it seems illogical to pass the access code in every request, even more so passing the user id.
The focus of this question is for me model a solid strategy for managing this authentication-user-identity behavior, would love any insights on how has this been done before since the material I've found in SO and the web has been very lacking, often referring just to server side implementations or just authentication answers, not addressing the issue of further requests.
The Facebook/User ID is there to identify the (returning) User. Keep in mind that you only get an "App Scoped ID", not the "real" ID - it will be unique in the App, but different in another one. See changelog: https://developers.facebook.com/docs/apps/changelog
Access Tokens are there to make calls to the Graph API. There are 3 different Tokens (App Token, User Token, Page Token), you can read more about them in those articles:
https://developers.facebook.com/docs/facebook-login/access-tokens/
http://www.devils-heaven.com/facebook-access-tokens/
You can store Access Tokens for later, but in most cases you donĀ“t need to store them - only if you need to access the API while the User is not using your App.
In general, App Tokens can be used to request public stuff and to change App settings. User Tokens can be used to request (or post) User stuff and Page Tokens can be used to request insights of a Facebook Page and other things.
If you want to deal with Access Tokens on your own, make sure to activate appsecret_proof in the settings. I suggest reading this article about securing API calls: https://developers.facebook.com/docs/graph-api/securing-requests

Can an Android App Grab CSRF Tokens from parsing web pages?

Lets say there is a website that doesn't provide an api service. However, a legitimate android app wants to provide a useful service. So first they ask the user to create an account on that website. Then once the user is logged in, they would be able to perform certain functions like "liking" a post, or commenting on stuff, right from the app. But obviously a CSRF token is used for all form submissions. So are android apps capable of grabbing this token? If not is there a way to ask a user for permission to grab it? Also if the same app was made for iOS would the functionality work the same?
Thanks.
Assuming the app makes the login request on behalf of the user and stores the authentication cookies for use in the subsequent requests, then yes.
A GET request would need to be made to the web page with the form on it, the CSRF token parsed and then a POST request would be made passing all the required parameters (including token).
Yes this could be done with iOS too.

Storing API key on mobile device

I've read many, if not all, answers to previously asked questions about the same topic, but questions themselves are not exactly about my case.
I have an OAuth 2.0 server running. It has an endpoint that provides access tokens to users. Programs and websites requesting the access token may or may not be owned by me, in other words, I may add a tool for website users and locate it on the same or neighboring website and my users may create an app and with their API key request access to user's data. Now I am developing the app that will operate user's data.
I realize that storing the API secret on the device is not a good solution. I have read about creating an end-point to which I make request directly from the app and then the endpoint makes API requests, but the endpoint will have to exist on the same host and probably server as OAuth server.
Is there a way to authorize mobile application to access user data when I am in controll of the application and the OAuth server? Should I create a separate end-point? Should I pass it device ID and/or any other information?
P.S. I know that plain old authorization would work here, but then what if some user wants to create his own mobile extension (not allowed currently for security reasons)? Also, current system has a button that is recognized by many people and they know what exactly will happen after clicking it. With the app, it may be an issue when the user sees a login dialog instead of the "Login with *" button. I really hope there is a clever solution to this.
Your concern is spot on. Your API Secret should not be stored on the device.
However, I am not sure why you would be concerned to build a separate endpoint, since OAuth 2 has a authorization flow for these use cases.
https://www.rfc-editor.org/rfc/rfc6749#section-9
In your use case, I'd suggest using the implicit grant flow to fetch the access token and store that on the local device. There would be no refresh tokens and the access_token can have an expiration date. Of course, the token on the device can be compromised, but the damage will be limited to a particular user and not the entire application.
If this level of security is not acceptable, then you can look at splitting up your API Secret in different parts of your app and then assemble it at run time in your app.

Getting a OAuth2 authorization code that can be shared with a server

My Android app needs to send an authorization code to my server so that the server can use that to acquire an access token for the user's Google Drive account. I have been trying to figure out how to acquire the authorization code and I found this in the Google API documentation (Using OAuth 2.0 for Installed Applications):
This sequence starts by redirecting a browser (system browser or
embedded in the application as a web view) to a Google URL with a set
of query parameters that indicate the type of Google API access the
application requires. Like other scenarios, Google handles the user
authentication and consent, but the result of the sequence is an
authorization code. The authorization code is returned in the title
bar of the browser or as a query string parameter (depends on the
parameters sent in the request).
After receiving the authorization code, the application can exchange
the code for an access token and a refresh token. The application
presents its client_id and client_secret (obtained during application
registration) and the authorization code during this exchange. Upon
receipt of the refresh token, the application should store it for
future use. The access token gives your application access to a Google
API.
Now I am not sure how to get this authorization code in my Android app since the Android examples I have seen seem to get the access tokens directly. I am looking at the Android AccountManager class and it has a method getAuthToken but this seems to refer to the access token and not the authorization code.
So how does one acquire the authorization code that can be shared with a server? If it is possible I would greatly appreciate some example code. If this is not possible what are the possible workarounds?
You may want to take a look at the Cross-client Identity document. It should keep you from needing to pass user tokens back and forth.
I believe you can actually take the access token returned by the Android AccountManager, send this to your server, then have your server make a call against the Google Drive API using that same access token - it is a bearer token and not bound to the channel that created it, so please take good care of it and only send over encrypted connections.
Documentation on how to get that access token can be found here:
https://developers.google.com/drive/quickstart-android
While that access token is good for immediate use, it will expire in less than 1 hour, so if you are looking for a solution that enables your backend server to have continued access to the Drive data, without the user being present at your app at the time of request, an alternate approach will be needed.

Google Plus Authentication within an Android App

I'm trying Google Plus sign-in in an Android app (with backend support).
I could get access token and email from the user, but know I don't know how should I recognise this user from the server. I'm sending this to the server (email and oauth token) with a POST throught SSL
Of course I could recognise them with their email, but that would open the doors for everyone how knows another email that's on the database.
How could I verify that the user's correctly authenticated and has sent me the correct oauth token for this email?
Thanks!
Two thoughts:
1) Generally, you shouldn't be sending the auth token over the wire if you can help it. Instead you should be using a hybrid flow where the client gets a one time code when it authenticates, passes you this one time code, and you can redeem this for an auth token and a refresh token. Using this method, your server also has offline access on behalf of the user. See https://developers.google.com/+/web/signin/server-side-flow for details. However, I'm not entirely sure how this works with the Android library.
2) Regardless of (1), generally what you can do is to use the plus.people.get method on the server with the userID of "me" to get the user's userID and verify this against what you're expecting. See https://developers.google.com/+/api/latest/people/get for more details.
Yours is a perfect case to use the Authorization code flow.
See this link. It has some workflow diagrams that you might want to see. In your case the user should authenticate and receive an authorization code (and not a token!).
He would then send the authorization code to your server, you can exchange this code for access + refresh tokens. Have your client registered for the scope and have the client credentials.
The access token flow (called the implicit grant flow) is generally used when requests need to be sent directly from the user's browser.
And, as #Prisoner already mentioned, you will have offline access too. That would be a much better design.
EDIT - you might also want to take a look at What is the difference between the 2 workflows? When to use Authorization Code flow?

Categories

Resources