I am creating a native Android app which currently uses Firebase Auth to handle user authentication. I have a MySQL database behind a PHP site and I'm building a RESTful API to access those services. I would like users who are authorized to be able to access limited features and data.
In this scenario, what would be the approach to handling the permissions on the backend server? I'm new to Auth techniques such as OAuth etc, but I get the feeling that might be part of this solution, so feel free to talk to me like I'm an idiot. :)
[edit]
My backend has similar permissions to Facebook; such as content is visible as either private, friends or public.
Regards
It depends on your security design.
The easiest way is to have a role-based security - use OAuth2/OpenID Connect just for authentication (ask for an ID token, not access token). Then you must get a list of roles for an authenticated user. The roles could be part of the ID token or the API server could get them from another source (e.g. its database). If the role retrieval is an expensive operation, you could consider issuing your own token (JWT) containing all the info you need.
If you wanted to delegate just some of user's permissions to the mobile app, you could register the API scopes (permissions) to the OAuth2 server and the app could ask the user for some of them. As an example, if your application wants to access Google services on behalf of its user, the application asks for an access token with specific scopes (e.g. reading GMail inbox). But this is probably not what you want.
Edit:
If the objects you deal with have access rights defined on themselves (private, public, friends visible), then just get a user identity (ID token) from the OAuth2 server and check the permissions when someone requests such an object by your API. OAuth2 itself cannot help you with that.
And for your Android app, use the Authorization Code Grant Flow as described in the OAuth2 for native apps RFC.
Related
I would like to discuss a common scenario: An app wants to authorize users using multiple OAUTH providers, such as Facebook, Google+ or Twitter.
Essentially this question has been asked two years ago here Mobile API Authentication Using Existing Web App with Multiple OAuth Providers and stays unanswered, so I will elaborate a bit further. (I will use Facebook as an example for the OAUTH2 provider, so this does not become too generic.)
Essentially, user registration works like this: OAUTH/OAUTH2 providers typically provide a workflow where a (mostly short-lived) token is obtained from a provider either via the AccountManager on the mobile device or a login dialog such as the "Login with Facebook" button. The token is then shipped to App Engine by calling a REST endpoint (either in the body or as an additional header, never in the URL).
The provider's AppId and AppSecret (here: Facebook) are store on App Engine and App Engine adds these to the token, then ships it back to Facebook in exchange for a (long-lived) token.
At this point both, client app and App Engine app have certainty that the user has been previously authenticated by Facebook. Also, if Endpoints Authentication is used to authenticate the call, App Engine probably has the Google credentials of the user and/or the ClientId of the app, and Google guarantees that the request has been made from the correct client app.
At this point, we can try to find the user in our datastore and let registration fail (or silently sign in the user) if it already exists, or otherwise create a record.
Until here I am pretty sure I'm on the right track. Now comes the problem:
Let's look at the datastore for this. Let's assume we have two entities:
User entity, where each user in our own system is registered under a unique user id.
Account entity, where each account is registered and where a userId field points to the User entity.
In relational database terms, we would say we have a 1:n relationship between User and Account.
For each User in our system, we keep a User record. In above example, we may have two accounts: Facebook and Google, which both point to the user and where the unique Facebook or Google id/email is used as account identifier.
Technically it would now be possible that the app uses the Facebook or Google account on subsequent requests. But we would have to store and look up the 3rd-party token on each request because we cannot decrypt it ourselves. We could ask the provider to do this, but that wouldn't make much sense either. Plus we would have to translate the provider's Account id to our own User id on each request.
To solve this problem I would most probably either create our own token or set up our own OAUTH provider which creates a token signed by our own system, and where the unique User id is used as identifier, and only use that token during subsequent requests.
Is this a good approach? Is anybody using a different better workflow? Does anybody see security flaws with this design?
Essentially it works around Google's endpoints system, but Google can only authenticate against their own systems, so if we want to offer sign-in using further providers, we will need to work around this, except if anybody knows a workflow where we can keep both, but then we have the problem that we can/should only add a single token in the "Authorization" header and REST principles discourage us to use custom headers to ship more tokens.
When your app authenticates a user, store an object in a session which contains an oauth provider that has been used to access the app and, optionally, a token to be used for subsequent requests.
Now you can check for this object in every call to the server. If the object is not present - a user is not authenticated, redirect to the login page. If an object is present, take a token and use it.
I use a similar approach for multiple authentication options, not only oauth. Except I don't need to store a token after a user is authenticated - I have no use for it within the app.
I'm developing a small app, I have an asp.net web application with a WCF data service. On my app, the data service is exposed to Android, and I want to authenticate the users.
The user's credentials will be stored in a database.
Is it possible to use membership and role provider to authenticate the users?
If not, what is the best authentication method, so that I can give permissions to some operations and deny it for other operations?
The option I've seen used often is to use HTTPS and pass through your user credentials on each call using a RESTful service. Obviously keep your security layer at the server side and return failure codes when the credentials aren't valid.
There are tonnes of examples on the web, including this SO answer.
New to OAuth2. I am writing an Android app that communicates with an App engine server application.
The app needs to authenticate itself with the server on behalf of the user, using Google account info of the user. The server needs to retrieve the user's basic info and create an account . That's the easy part and I know how to do this.
Furthermore, the Android app will also have the user authenticate himself/herself using Oauth2 and retrieve basic user info using Google account info of the user. I can do this as well.
This is where I need help Assuming the previous steps have been completed successfully, how can I use the Android app (where the user has logged in) to communicate with the server securely using the user's credentials.
Any ideas or am I missing something obvious?
The Android to App Engine OAuth2 communication is documented in this answer:
google app engine oauth2 provider
Using OAuth, 1.0 or 2.0, doesn’t matter in this, leads to the app obtaining an access token - then based on the API of your server, you pass this access token with requests instead of login and password. I guess the way to attach the access token string to URL requests may be slightly different between different APIs, see the documentation for yourself. Or if you are making the server app at the same time, then you need to figure out your way to do so (like sending a HTTP header Authorization: OAuth access_token=abcdefgh….
We're currently in the process of implementing OAuth2 to secure our new API and not sure how to securely provide required functionality. We need to allow the following from a mobile device:
Immediately after downloading the app the user is able to take a picture and submit it without having to first log in.
While we want to allow anonymous user access, where a user does not need to log in or register to use certain functionality, we do not want to allow unauthenticated access to the API. This would normally be accomplished using the client credentials authorization flow to obtain and app access token, however this requires knowing the client secret. From what I've read, a mobile device is not considered a trusted client and should not contain the client secret, and hence should not be able to generate an app access token on its own.
We've come up with a few options to accomplish this requirement, but would like some input on them:
Embed the client secret in the app. Doesn't seem ideal from a security standpoint, but maybe we're missing an obvious way to secure it? We're targeting at least iOS and Android.
Generate an app access token offline and embed that in the app. Still not very secure, but at least the secret isn't exposed.
Allow access to certain functionality using only the client ID instead of an access token. This may be the simplest, but it introduces an inconsistency and requires multiple ways of authenticating the client.
Build and use a companion web app to generate app access tokens for the mobile app. On the surface seems like a winner, but now you have to secure access to the companion app!
How would you securely authenticate access to an API using OAuth2 from a mobile device without requiring the user to first log in?
Agree with the comments on the Q. Either:
1.) Use Client Credentials grant type in OAuth 2 - with an embedded secret in your App. Understand that this isn't super secure and someone will reverse engineer it eventually. Ideally each client would get a unique secret - so you could revoke a client if they're abusing its use.
2.) Live with that API being open - thereby not requiring an OAuth 2 access token at all. Maybe that API would be known only to your app - but again, it would only be a matter of time before someone reverse engineers it.
My group is having a similar discussion. Users can get the app and browse a catalog without having to sign-in. The catalog and other data is accessed via an API and we would like to force users to have an access_token for all calls.
Our current thinking is to
Always force the App to exchange a common clientId/secret for an access_token. So the app would get an access_token even for anonymous users. This would be via the client_credentials oAuth flow.
If the user signs in, use the oAuth password flow. They would pass in clientId, secret, username, and password. We would additionally allow them to pass in their anonymous token so that we could transfer any history from their anonymous session.
So for example...
access_token = api.oAuth.client_credentials(clientId, secret)
catalog = api.getCatalog(access_token)
authenticated_access_token = api.oAuth.password(clientId, secret, username, password, access_token)
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.