Securing my REST API with OAuth while still allowing authentication via third party OAuth providers (using DotNetOpenAuth)

Nathan Ridley picture Nathan Ridley · Jan 1, 2011 · Viewed 69.8k times · Source

I have a product with a straightforward REST API so that users of the product can directly integrate with the product's features without using my web user interface.

Recently I have been getting interest from various third parties about integrating their desktop clients with the API to allow users of my product to access their data using that third party application.

I've seen that applications that want to use Twitter authenticate using a login page hosted by Twitter that grants a specific application permission to access that user's data. You click the "Allow" or "Deny" button and the authentication process is complete. Facebook uses the same mechanism as best I can tell.

Upon further research, this seems to be OAuth in action, and seeing as my API is .Net-based, I am thinking I should use DotNetOpenAuth and provide a similar mechanism. Unfortunately the samples are sparsely documented (if at all) and the only tutorials I can find online seem to be focussed on helping you provide a login mechanism for your users so that they can log into your website using a third party provider.

What I would really like to do is have my REST API handle all of the core authentication and business logic for my web application and have, under the hood, my web application essentially be another application that just uses the API via OAuth. Users would authenticate on the website either directly using their username and password, or via a third party provider such as MyOpenID or Facebook and then the website would somehow use the returned token to authenticate against the REST API.

Architectural Diagram

It basically looks like I need my API to somehow host an OAuth service, but also have users use a third party OAuth service. I can't help but think I don't quite have enough of a grasp on OAuth to decide if I'm overcomplicating things or if what I'm trying to do is a good or bad way to do things.

Can someone give me at least a broad overview of the steps I need to undertake, or what I should look at to make this happen? Or point me at some tutorials? Or blast my proposal and tell me I'm going about this (architecturally) all wrong?

Answer

Andrew Arnott picture Andrew Arnott · Jan 5, 2011

First I'd like to emphasize the difference between authentication and authorization:

A user authenticates to your web site by supplying some credential such as a username+password. OpenID allows this to be displaced by having the user authenticate to another service, which then asserts the user's identity to your web site on the user's behalf. Your site trusts the third party service (the OpenID Provider) and therefore considers the user logged in.

A service or application does not authenticate to your web site -- at least not typically. A user authorizes a service or application to access the user's data. This is typically done by the application requesting authorization of the service provider, then sending the user to the service provider, where the user first authenticates (so the service provider knows who its talking to) and then the user says to the site "yes, it's ok for [application] to access my data [in some restricted way]". From then on, the application uses an authorization token to access the user data on the service provider site. Note that the application does not authenticate itself as if it were the user, but it uses another code to assure the service that it is authorized to access a particular user's data.

So with that distinction clarified, you can make decisions on your site about authentication and authorization completely independently. For instance, if you want your users to be able to log in with all of: username+password, OpenID, and Facebook, you can do that. A completely orthogonal decision is how you authorize applications (there are many protocols you can use for this, OAuth of course being quite popular).

OpenID is focused on user authentication. OAuth is focused on application authorization. However, a few services such as Facebook and Twitter have chosen to use OAuth for authentication and authorization instead of using OpenID for authentication and OAuth for authorization.

Now for your own project, I strongly recommend you check out the ASP.NET MVC 2 OpenID web site (C#) project template available from the VS Gallery. Out of the box it comes with OpenID authentication and OAuth Service Provider support. This means your users can log in with OpenID, and 3rd party applications and services can use OAuth to make API calls to your web site and access user data.

What it sounds like you'd want to add to this project template once you get going is the ability for your users to log in with username+password as well as OpenID. Also, if you want Facebook and Twitter to be an option for your users you must implement that as well since they don't use the OpenID standard. But the DotNetOpenAuth download includes samples for logging in with Twitter and Facebook so you have some guidance there.

I suspect you won't have much if anything to do on the authorization front. It comes with OAuth as I said before, and that will probably suffice for you.