When to use Oauth and API key authentication types - api

I get it that Oauth is used to grant permission to a third party application to access a user's data (like photos on his facebook account) without revelaing his facebook credentials to the third party application. For example, when you try to use an online photo editing tool and you want to load a photo from facebook, facebook will pop up a message asking whether you really want to allow the application to access your data. So at that point facebook just returns a temporary access token and the app can use it to access your facebook photos. (as i understand the scope for this access token is such that it only has permission to access the particular user's photos only) Yes, this sort of a setup is required because you can't trust a third party application that much as to give away your credentials.
Assume somehow instead of oauth, facebook used api key authentication. This would mean that all third party applications that have subscribed for facebook API already have a key which they can use to access facebook's data sources.So that the app can directly take you to your facebook photos and facebook will not notify you that an outsider is trying to access your private data. This approach is not suitable for an api that exposes user sensitive data but for apis that expose not so user specific (like google maps) data, the api key approach should be enough, right ?
So my question is, what are the criterion to decide which authentication type should be used ? And appreciate feedback if my understanding is wrong.

Here are 2 of the standard 4 Oauth2 flows which cater for the scenarios you mention.
Authorisation Code
Client Credentials.
Using your Facebook example above you could think of like this:
Use Authorisation Code flow for your "Oauth" scenario, where your app needs delegated authorisation to access a user's Facebook photos. This means the user must login and grant access to your app and your app must have an API key (client ID) issued by Facebook.
Use the client credentials flow for your "API Key" scenario. This would be when your app needs access to, for example, public Facebook pages / info and thus does not require specific user consent and can just use its API Key (Client Id & Client Secret)

Related

What is the correct way to use OAuth for mobile and website consuming my own API?

I have a question more related to the way OAuth 2 is working but since using IdentityServer to implement OAuth I think it's relevant. I could not find an answer anywhere.
I'm building a website and a mobile app that consumes my own API. Each user of my app will have a username and password, that will give him access to the app/website and though the API to his information.
I'm not sure about the right way to handle the flow for user login:
On the website I have my own designed login form. I don't want to move the user to my auth server to login, and then have him approve the information he gives - he is the user on my system - I have access to all information - kida like facebook has a login and access to the informatio - they don't ask what you're willing to give them. So is implicit really the way for this?
On the mobile app I also have a login form and now I read here (https://datatracker.ietf.org/doc/html/draft-ietf-oauth-native-apps-10) that the OAuth approach is to have the login in a WebView?? Doesn't look like facebook login is in a WebView on their mobile app.
The approach I was first lookin at is the Resource Owner. Users will login, get the token and the refresh token and can start working against my APIs. But storing my client_id and secret on the mobile app? on the website javascript files? doesn't feel right. I can of course make a call to an API that will mask those and be a proxy to the login process... but... (read #4).
In the future I would like to allow access for third-party developers. For them to allow login for users of my system I will use the implicit flow. Also, I plan for those developer accounts to have restricted API access (for example, the number of calls to the API will be limited by plan). What prevents those developers from asking for the username and password of their account on my system on their website, getting the response from my servers with the access token and refresh token, and using my API however they want, without restrictions, and having access to the entire user profile?
Lets say I'm sticking to the resource owner flow, receiving back from the server a token and a refresh token. What should I store on the mobile device and how? What should be stored in the browser and how? the refresh token? and each time he opens the app get a new updated token with that refresh token?
Edit
Just to clarify, because I find a lot of lectures and articles that explain the process from an API consumer point of view (ie. the third-party developer): I am the API owner and the auth server owner, I'm the owner of the user accounts (they are my users of my services), I'm also my own consumer (though the website and the mobile app), and in the future I want to enable third-party developers to allow my users to login with their accounts of my service (kinda like Facebook or Google)
You're correct that you shouldn't store the client_secret in your app, but I doubt you will get around storing the client_id. You could disable the consent screen for your app as well, and build a native login view. You need to store the access_token and the refresh_token on the device (maybe encrypted in a database) if you don't want the user to login everytime they use your app.
As for problem 4, you could do the following:
Embed the client_secret in your (web) app
Set up which hosts have access to your api on the IdentityServer
The IdentityServer generates a salt and sends it to the client
The client calculates a session_secret using hash(ip_address + session_salt)
The client uses the session_secret and the client_secret for the API call
Server validates the hash and client_secret
It's nearly impossible to completely prevent someone from using your API. But you should add various rate limiting methods, such as limiting IP addresses, API calls etc. But nothing will stop someone decompiling your app and accessing your client_id.

Authentication for new Twitter API 1.1

I have an application that needs to display number of followers and following (users/show.json) for a random user on a public page (authentication is not required).
With the Twitter API 1.0 it was quite easy as authentication is not needed for the request. With the new Twitter API 1.1 is no more possible, so I need to authenticate the request (via OAuth).
Is it possible only "authenticate" the application and not the user too?
I mean: can I avoid to ask user to login and only authenticate with application key/secret? Or everytime I need to create a token with user credentials too, creating callback, etc.?
Yes, it is possible! If your application doesn't need to do things like post statuses or send direct messages on behalf of a user, you should be able to retrieve all of a user's public information with a single hardcoded set of Twitter OAuth credentials, and not require the user to authenticate.
Login to Twitter and go to the developer dashboard at https://dev.twitter.com/apps
Register a new application; after the application is registered, view the application details. You'll see an "OAuth Tool" tab, where you'll find all the relevant OAuth values for that application: Consumer Key, Consumer Secret, Access Token, and Access Token Secret.
Using these credentials, you'll be able to make requests to the new Twitter API.
If you're not comfortable using the Twitter API directly, there are a number of good API wrappers out there for various languages -- among others, the Temboo SDK, which will give you code snippets for calling various methods (and also gives you a place to securely store your Twitter credentials, so you don't need to bake them into your application).
Take a look at:
UserTimeline
GetFollowersByID
(Full disclosure: I work at Temboo.)
The easiest way to do what you're asking is to use Twitter API 1.1's 'application-only authentication' feature, which works for much of the API. See Application-only authentication. You can see a Python example of it in get_bearer_token.py.
Once you have a bearer token, you only need to include that in your request authorization header - signing is not necessary.

Login to Single Page Application with Google authentication and Google Oauth 2.0

We are developing an SPA - full client base javascript application and need to authenticate our users to get access to the internals.
As I found from the search we can outsource our authentication mechanism and use Google accounts for that. I learned from this site
https://developers.google.com/accounts/docs/OAuth2Login -
How to deal with Google API and mechanism for authentication.
In the short word, we need:
send request to google url with params to ask user to allow SPA use their personal data
in case of success we get a token from Google
we may use this token to get access to API we were asked and work with it.
This is described well and I understand it and have some JS code to make it happen.
What I do not understand.
I have an application with it's private data. I want use user's e-mail as the login, or user id (doesn't matter how to call it) to access app's internals, such as user's created tasks, user's profile, etc. So, to display user's created tasks in my SPA I need query database with the user's e-mail.
I imagine the next scenario:
user click Login with Google button
we obtain an token - this means user was authenticated successfully
we persist user and his e-mail to work with SPA
when user click Logout we clear all access data
Where should I persist this data?
In case of Forms Authentication I understand that we pass login/password to server and if they match the database we create Forms Ticket and store it in cookie.
Is there any similar case with Google's auth? If I'll store user's email in cookie I think that's not very good from security reason. If I'll save a token - I'm not sure why I need it and how to use it in my SPA, I'm not using any Google API after authentication.
Do you have any example case how do we build our process in similar cases?
Thank you.
If all you need is the user's email address, then you would be better off using OpenID instead of OAuth. OAuth provides access to a user's account and services, scoped to a specific resource or set of resources. OpendID is designed just for logging into a third-party service. You can then extract the user's ID and email address from the OpenID login. Note: The ID will always be sent but the email address has to be explicitly requested during authentication.
Google also supports a hybrid OpenID+OAuth scheme that lets you piggyback OAuth requests on top of an OpenID login if there is some resource you need to authenticate to. Take a look at the authentication document to get an idea of how both protocols work and which is better for your scenario.
Once you have the email address returned, you probably shouldn't persist it in a cookie. The normally recommended way to handle it is to add it as a session parameter. That way only the session cookie is stored on the client, and the server can use it find the values it needs. This answer has a good explanation of the differences and when you want to use sessions versus cookies.

How to authorize mobile apps with a third party by oauth BUT connect to my service, not the 3rd party

My app is architected as follows: I have a web service (running on GAE, not very relevant to this question) and the data that this service contains is made available through a website and through mobile and desktop apps.
Currently, the user authenticates to the website via Google ClientLogin and the apps authenticate/get authorized via GAE's built-in oauth provider. (OAuth is being used here mostly for authentication, my app doesn't actually use any external data via OAuth other than the user's unique ID and email address.)
What I'd like to do is expand the number of services that users can use to login. Because of the complicating factor of the apps, it seems I need OAuth. But I can't really properly conceptualize how this flow should go.
Lets take Facebook as an example. When a mobile app goes through the Facebook oauth flow and acquires an access token, this isn't enough - because its my service, not the app, that actually needs to talk to facebook to retrieve contact info and a unique user ID. This leads me to think that the OAuth process needs to happen in the context of my service, and not the mobile app. My service then becomes the consumer and Facebook the oauth providor, and the service holds on to the oauth access token, this happens when a user sets up their account for the first time.
If this is the correct approach, where does that leave authentication for the apps? What happens when the user already has an account and installs a fresh instance of a mobile app? I imagine also going through the oauth process, matching up credentials with the data already stored by my service, and then issuing my own "access token" to the app from the service, to authorize that instance of the app. This seems convoluted and hackish.
I'm sure I can't be the only person who is in effect "borrowing" the account system of a third party for a mobile app with a backend, but I really don't see what the proper way to do this is.
What am I not seeing and/or getting conceptually wrong?
A few colleagues and I once did a project quite similar in nature, back in university. We authenticated our users through either Facebook or Foursquare, using their respective OAuth APIs.
The native Android version of the app opened up a WebView with the OAuth provider's start page, which redirected back to our service after authentication. Then our service did a request for the OAuth token from the OAuth provider (Foursquare has some pretty simple instructions). When we got that token, we set up a session using cookies, which we could access from the app.
To validate sessions, we just checked whether the access token was still valid with the provider. We also used the respective providers' unique user IDs to distinguish users.
So yes, what worked for us is: Make the app authenticate & authorise your service, not the app itself.

how can I authenticate a user from a web app to an API?

It seems to be a widely asked questions and after having read tons of documentations on the subject, I'm still not sure to have understood everything correctly (I assume that being dumb is a possible answer ;)).
I'm trying to build an API that will provide a service to users. The users will be connected through Facebook or any OpenId provider (I separate Facebook since their implement their own connecting system).
(I think it's a good way because I will not store the user's password and finally will have less problem in case of a similar Gawker issue.)
When a request is made from the client (web app, mobile app, whatever) to the API, an indicator must be sent with the request in order to identify which user is using the app. This is generally used via a token, defined during the Authentication.
But regarding the Authentication, I can't find any valuable example, tutorial, explanations about how to implement it correctly.
I'll (try to) explain :
In my (wonderful world of happy care bears), I structured my project in various parts :
A RESTful API
A web apps that will use the api. Ideally, I was thinking about making a complete html/css/js project, without any server side work (php/python/java or whatever)
A mobile application
An windows/mac/linux application
As far as I saw, every time someone ask how to implement a RESTful API authentication, three major answers pops out :
The HTTP basic( + preferably SSL)/digest way
OAuth
OpenId
Since I will not store the user's password, the first one is out for me, but the two other leave me perplex.
But OAuth and OpenId are not the sames, one (OpenId) stand for the Authentication (that the base of the questions) where the second (OAuth) stand for the Authorization!
When Twitter implements OAuth for their API, they are not implementing an Authentication system, there are setting up a way to indicate their users that the application X want to have access to the user account (in various level of access). If the user is not currently logged in Twitter, he will first have to authenticate himself, and then authorize the current application to access his data.
So, just to clear things up, OAuth is NOT an authentication mechanism, it's a :
An open protocol to allow secure API
authorization
(source: http://oauth.net/)
Then, the only way to authenticate a user would be using OpenId. And then, the hell comes true.
If I take as an example a web application that is exclusively made of html/css/js, with no server side components, communicate with an API.
The web app must indicate to the API that the user currently using the API is mister X.
To do so, the web app show a popup containing a list of OpenId providers, asking the user to authenticate himself. The user click on one of them, get redirected (or a new popup open up) to the OpenId provider, indicate his login/pass, get authenticated by the OpenId provider, that return the success with a token (I simplified the communication).
That's great, the web app know now that the user is really mister X. But the API still have any clue !
Finally, my question is quite simple : how can I authenticate mister x through the web app to the API via OpenId and after that, how can the web app and the api keep the information that this is mister X that is currently using the web app and of course, the API.
Thank you very much for your help !
-edited format
You don't really want to login to the API using OpenID. As you said, OpenID is for Authentication, i.e. Who, while OAuth is for Authorization, i.e. am I allowed? But your structure suggest you'll be using an API as a backend and a web app as a front-end.
The best way then is to use OpenID on the web-app to authenticate the user, and then the web-app connects to the API and stores the OpenID credentials. The web-app then knows who the user is, and can provide the service. The API has nothing to do with the user, except that it stores its data.
The fundamental difference between OpenID and OAuth is its use. In your situation, you could have something like that:
-------- --------- -------
| User | <------> | App | <--------> | API |
-------- OpenID --------- (OAuth) -------
The User never interacts directly with the API: who would want to manually send HTTP request? (lol) Instead, the service is provided through the app, which can optionally be authorized using OAuth. However, in the case of a single app accessing the API, you can make the app <=> API connection internal and never expose it.
(If you don't want to read, the list bellow sum up the whole idea)
A possible solution (tell me if I'm wrong) would be to display the login form in the consumer (web apps, mobile apps, etc), the user click on it's provider (myopenid, google, etc) that opens a popup to do the login.
The tricky part is that the return_to parameter would be set to the API, not the website
The API will then resend the check_authentication and get the is_valid:true (or not).
During this step, the app would query the api to a specific url that return the state of the authentication (processing, failed, success). While it's procesing, an indicator is displayed to the user (loading gif), and if it's success/fail the result is displayed to the user.
If the api receive a is_valid:true, then it will ask informations about the user to the openid server, like email, firstname, lastname, and compare them with it's user's database. If there is a match, the api create a session between itself and the app, if the user is new, it create a new entry and then the session.
The session would be a unique token with a specific duration (maybe equal to the openid server assoc_handle duration ?)
It seems to be something possible, but I'm not an expert in security.
In order to explain things simplier, here is a little "map" :
Note: Provider is the OpenId server (that provide the informations about the authentication)
The User go the webapp and click on the login icon of his provider (Google for ex)
The webapp opens a popup containing the provider login page and access page, and specify a return_to to the Api
The provider sends informations to the Api
The Api validate these informations via the check_authentication
If not valid, the API indicate to the webapp (that ask the api every x seconds) the failure
If valid, the Api asks informations about the user to the provider, like email, display name, etc
If the user exists, a session is created
If the user is new, he's added to the database and the session is created
The Api returns the state of the auth (in this case, success) with a token session that will be used by the web app for further requests.