I am creating an Android app that will be using a Django backend, along with the Django Rest Framework. I have been reading the OAuth2 documentation, but am still struggling to understand a few key points about its authentication.
These are my main questions/things I'm struggling with:
In OAuth2, I am given the oppurtunity to create 'apps'. Would the 'app' in this case be specific to my Android app (and presumably in the future I would create a different one for a potential iOS app?).
Will all users of the (Android) app be using the same token, or is each user granted an individualized token?
I am using the Volley library for Android to deal with networking. How do I go about getting the Android app to 'store' the needed credentials? Would I be storing the token, id, and secret, or just the token?
If it is worth noting, I do not plan on adding social media logins (Facebook, Google, etc) I will just have login be with a username and password.
I'm sorry if these questions seem a bit elementary, this is my first experience will authentication of any sort.
Thank you
I'll be using the word "app" to mean two different things:
app, to indicate Oauth2 app, which you'll create to register your mobile app(s)
app, to indicate mobile app.
Answer 1:
An app is basically a way of registering a client (in this case, your mobile app) with the resource server (in this case, you Django backend). You can go either ways, creating two separate apps or a single app for your Android and iOS apps. Unless you are not planning to give users of one app some more privileges or features, I don't see benefit in creating two separate apps.
Answer 2:
Each user is granted a different access token.
Answer 3:
You'll have to store client_id and client_secret in some secure way on your mobile app(s). Because that's what will help you gain an access token for a user, in first place. You'll also store access token after obtaining it, because it will be needed in making authenticated HTTP requests.
For more information on Oauth2 Protocol in general, you can read this answer, and Oauth2 Protocol RFC.
Related
I have an android native app as client and spring boot service in the backend with REST endpoints. I want to know the best possible strategy for authentication with oAuth2 (without the social login approach).
I am currently using spring oauth security & have an authorization server up and running(user signs up with email & password). I use the grant type "password" to get access tokens in the android app. However, this approach requires the android app to send the client ID & secret in the request. I read a few posts which suggest that this grant type is not ideal. I dont mind receiving the user's password, but i think storing the client secret in the app is not a good approach.
Another approach would be to use the Authorization Code grant flow, but in this case since i only have a native app & backend APIs, i dont know how to authorize the user. It doesn't seem like a seamless experience for users to see a browser page asking them to authorize the app. Which doesnt make sense also because this is no third party app.
I found a post where people suggest using Authorization Code flow with PKCE. But this apparently doesn't yet work with spring.
So, now i am left wondering how other native mobile apps, handle authentication? Do they not use access token? How best can i support authentication when dealing with a mobile app & spring backend?
Spring Security OAuth supports password and authorization_code flows without the client secret, meaning a "public client". Since you own the Authorization Server and the native app and you are okay with the native app taking credentials, it's reasonable to have your native app use a public client with the password grant type.
If you decide that your native app shouldn't take credentials, though, then PKCE is the current best practice. Using the authorization_code flow with a public client is the recommended alternative to PKCE:
In the time since the spec was originally written, the industry best practice has changed to recommend using the authorization code flow with no secret for native apps.
And this would mean, as you mentioned, jumping out to a browser.
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 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.
I'm currently designing a service that will be half web app, half android app. Each user will need to be able to log in from either the android app or the web app, using an openID account. I'm hoping to target Google first for easiest integration with Android, but I'll also need some OAuth stuff later so that I can integrate with Google contacts.
The bit I'm having trouble with is how to authenticate users. The structure I've planned is that the server (probably using web.py, although that's flexible right now) serves data for the client in JSON, whether the client is the javascript browser client or the android client. However, each call needs to make sure the client is allowed access to that data.
What would be the easiest way to standardise this across the platforms?
Should I be using a session system to authenticate after logging in? Can that be made to work from an Android app? Otherwise, should I simply authenticate with google for every request?
When authenticating from the app, where should the authentication happen, through the server or straight from the app? Where should the auth token be stored in this case? (I'm assuming for a straight webapp the token should just be stored in a table in the user database?)
Sorry for the barrage of questions, but I haven't really found any resources online that clarify these issues very well.
As long as you are using HTTP, the platform doesn't matter. You can use the same form of authentication and/or sessions. The only difference would be that on Andorid you might be able to get an authentication token using the platform's AccountManager, without having to type the username and password in Google's login page.
There's a subtle difference between Authorization (OAuth) and Authentication (OpenId). Make sure you know what you are doing.
I'm developing an android app that consumes a webservice that I will develop too (I'm thinking in using a RESTFul webservice)..
and I want to secure the connection between the app and the server but I need to authenticate users too..
My problem is in the last part, to secure the connection I think the best way to do it is to use SSL (https), am I wrong?
I don't know what's "the best way" to authenticate users, to make sure that a user cannot consume the webservice as another user..
I have some ideas, like using a authenticate(login,pass) method on the webservice that returns a token.. And for any operation that requires authentication the user would need to pass that token as a parameter.. The thing is, is this a good way to do this? whats the most common technique used to auth users in a situation like this?
If a token based auth is a good idea how should I generate the token?
Sorry for this long text..
Any help will be usefull
Thanks
Make sure you understand a trendy standard like OAuth before you go down that path. Most OAuth flows are centered around a user logging in to your server through a web browser. This can lead to pretty bad user experience for a mobile app. The standard does allow for alternatives. Here's a decent introduction.
You could also use an existing identity provider like Google, Facebook, Twitter, etc. instead of implementing your own authN/authZ. On Android, you can ask for a Google auth token using the AccountManager. This usually works because the user needs to be logged in to their Google account to access the Android Market. Anyway, this will prompt the user to grant authorization to your app. You could then use the Google auth token to login your user to your service with your own token. The login would essentially be your server verifying the Google token is valid (by contacting Google's servers) and then issuing its own token to be used for calls to your web services. If you don't like Google, you could use the Facebook SDK, etc.
As for what to use for tokens... The OAuth spec has stuff on that as well. You could do something as simple as a random string or something as complex as encrypted SAML assertions.
You should implement a token based OAuth, which will require the users to log in once, and then permanently have access.
You can use Google App Engine which already provides user authentication services for you (your Android users most likely already have google accounts) But this is only one of many options.
You can also look into Amazon's Identity Access Management (IAM) which will allow you to manage the users who have access to your web service, and authorize them accordingly.
I think the best way to do it is to use SSL (https), am I wrong?
This only prevents certain types of malicious use, but not everything. There is still nothing to prevent people from accessing your database on the phone, and retrieving credentials that way.