OAuth 2.0 in Web API

This week I’ll be pushing a sample to the WebAPI-Prototype branch in our Codeplex repository for doing an OAuth 2.0 dance for Web APIs.  Before I get into how the sample works, let’s quickly define some OAuth 2.0 terms (note that these are all defined in the OAuth 2.0 spec, but I’m defining them here so that you don’t need to read the spec as a prerequisite for this blog post).

Some Context

Resource owner – represents the entity who actually owns the protected resources.  In the case of this sample, the user (e.g. – you) is the resource owner.

Client – represents the application which accesses a resource owner’s protected resources after the resource owner has explicitly granted it permission – this last part can also be said, “after the resource owner has authorized the client to his/her protected resources”.

Resource Server – represents the application that is responsible for hosting the resource owner’s protected resource.  The resource server uses access tokens when processing and responding to requests for protected resources.

Authorization Server – represents the application that is responsible for authenticating a resource owner, enabling the resource owner to authorize a client, and ultimately issuing an access token to the client.

As the OAuth 2.0 spec defines, the abstract flow appears really simple:

diagram

However, in practice, nothing is ever as simple as the abstract flow makes it seems (that’s probably why they call it “abstract”).  For each of the stages of this flow, there are multiple ways of accomplishing the stage.  In this post, I’m going to discuss one way of implementing the OAuth 2.0 flow, but know that this represents only 1 of several possible options.  Moving forward, I plan on adding more flows into the prototype branch (and of course, blogging about them here).

A Brief Disclaimer

I’m a big believer in the principle of “the right tool for the right job” – and as I’m building out this prototype, one of the thoughts I keep arriving at is that while OAuth gives you authentication as a byproduct of having the resource owner authorize a client to a resource server, the focus of OAuth seems much more on authorization than it does federated identity.  I think that what I’m getting at is in the difference between delegated authorization and federated identity, but I’m having a hard time getting to a crisp, non-philosophical articulation of the differences between those 2 terms.  Judging from a quick Google search, I’m not the only one having trouble coming up with a clean articulation of the differences (I suspect this is because authN is always required at some point to do authZ).

At any rate, you may end up asking yourself a similar question as we go through the discussion of the sample, so I wanted to be up front in saying that I feel the same sense of weirdness and am also actively investigating OAuth patterns that use a federated identity system for authN and OAuth for authZ (or patterns to simply make it easier to integrate with federated identity systems, if simply not managing credentials is really the thing you care about).

The OAuth 2.0 Sample Workflow

For the sample, the goal was to secure a Web API using Facebook’s OAuth 2.0 capabilities so that the Web API didn’t need to maintain any usernames or passwords.  The resulting workflow looks like the following:

diagram (1)

As you can see right off the bat, the concrete example is a good bit more complex than the abstract flow defined by the OAuth 2.0 spec.  Why is that?  As I see it, there are 2 primary drivers of the added complexity to the end-to-end flow.  First, I decided that my Web API represents my OAuth client.  This means that once authorized by the resource owner (e.g. user), my Web API can get resources directly from the resource server (e.g. Facebook) without having to expose that data to the resource owner, or any malicious application pretending to be the resource owner.  However, because the end user experience is still a browser, and because my browser experience is AJAX-based (meaning that I can’t count on the browser to act directly on 302 status codes), I need a mini-protocol between my Web API and my AJAX code.

The second reason for the added complexity relates a bit to the “brief disclaimer” above.  That is, this workflow takes advantage of the fact that authentication is required for authorization – and my Web API client does call into Facebook (in its resource server role) to get some resource owner data.  However, the Facebook access token is used by my Web API only long enough to get a piece of user-identifying data which it then plugs into an existing authorization store – I’ve faked out the ASP.NET membership provider in this case.

I’ll be writing another post on my general thoughts here, but for now, this workflow works (even with the additional complexity) and should set the stage for showing how AuthN/AuthZ can work for Web API.

Plugging into Web API

One of the goals I had for the prototype was to enable the auth mechanism to plug into Web API using the standard extensibility points.  Additionally, I wanted it to use the standard AuthorizeAttribute that MVC uses.  As such, I took advantage of 2 Web API extensibility hooks: operation handlers and message handlers.  Additionally, there’s some logic behind wiring everything up that I encapsulated into an extension method that works with the HttpConfiguration object.

First, we have the OAuthFacebookOperationHandler.  The responsibility of this operation handler is to examine the incoming request to see whether the operation being called needs to be protected and if so, determine whether the user has been authorized (currently making this determination using a cookie).  Based on whether or not the user has been authorized for the operation, the handler will either pass control over to the operation or return a standard Http challenge response containing the Facebook OAuth authorization dialog URL.

First, I’m sure you’ll notice that there’s a bunch of todo notes still in the code.  I’m actively working on getting this more seamlessly plugged into things like the membership provider, the AuthorizeAttribute, and the forms authentication cookie generator.  However, the purpose of this post is to show the mechanics of initiating an OAuth flow, so hopefully those unfinished aspects won’t be too big of a distraction.  But that aside, the basic workflow looks like this:

  • check to see whether the user has already gone through the OAuth dance, been authenticated, and has authorized the Web API.  If this process has happened, there will be a cookie in the request
    • If the user has been authenticated, authorize the user based on the AuthorizeAttribute on the service operation
    • If the user has not been authenticated, throw a 401 challenge response with a scheme of OAuth and a location parameter of the Facebook auth dialog

In my sample, I have an AJAX client, so the following jQuery is able to take the challenge response, parse out the location and popup the Facebook auth dialog…

Like I said, this jQuery uses a regex to get the value of the location parameter in the response.  It then uses that to open the Facebook auth dialog.  The user will then interact with Facebook to authenticate and then authorize my Web API to a Facebook application that I created (note: you’ll need to create register an application with Facebook to use its OAuth authorization server endpoints).  If you look back at the URL that’s passed to the location header (line 45 of the operation handler), you’ll notice that one of the query values is the redirect URI.  My operation handler will always generate a value that is the address of the originally requested resource with an additional path segment called “authtoken”.  Therefore, if my resource is localhost/comments, the redirect URL will be localhost/comments/authtoken (this isn’t a requirement of any kind – it was just how I put this code together).  The thing is, I don’t have a resource or service named authtoken.  So how does this get picked up?  Enter the OAuthFacebookMessageHandler.

If you remember from Glenn’s post about Web API extensibility, message handlers give you an opportunity to plug in down in the channel stack and work directly with HttpRequestMessage and HttpResponseMessage.  And while this isn’t terribly helpful if you need details about the operation (parameters, return values, etc.), it’s great if you need only work at the Http level – and it’s very fast!  In my case, I need to basically capture all requests that have authtoken as the last path segment, get some information about the user from Facebook so that I can correlate that with my local authorization store (e.g. membership provider) and then drop a cookie that can be used in subsequent requests.

As you would expect, this code takes in an HttpRequestMessage.  However, because it’s task-based, it needs to return a Task<HttpResponseMessage> rather than just an HttpResponseMessage.  With async operation handlers, the basic principles are as follows:

  • To continue the flow of execution to the inner message handler and ultimately up through the service operation, call base.SendAsync(..) .  If you want to do some processing on the response side only, after the operation has been called, call base.SendAsync, but then add a ContinueWith(..) call.
  • To short circuit all further processing of the request and simply return a response, return your own Task<HttpResponseMessage> using Task.Factory.StartNew(..)

Because there is no actual service operation for /authtoken, I’m really dealing purely at the Http layer, so I’ll just be returning a new task rather than allowing the incoming message to propagate – and within my request processing I’m doing the following things:

  • Exchange the auth code returned to me from Facebook for an access token – this is the thing that is actually used to access Facebook data
  • Use the access token to get my username
  • Drop my username to a cookie so that my operation handler can pick it up on subsequent calls (note: don’t EVER, EVER, EVER actually do this in production – I’m trying to show you the mechanics of the OAuth dance, and only that)
  • Emit some script to close the popup window

If all is successful, this handler will set future calls up for success, then signal the parent window to both close the popup and retry the newly-authorized request, so that while there’s a lot of moving parts here, it feels pretty seamless for the end user.

Finally, there’s the question around how all of this gets wired up.  I extracted the configuration code into a single, more simple extension method:

This means that I can register for OAuth with code similar to:

config.RegisterOAuth(new FacebookOAuthClient(FB_APP_ID, FB_SECRET));

Where To Next?

There are a bunch of identity and auth related scenarios that I’m currently prototyping, in addition to cleaning up some of the hard-coded stuff in this one.  Here’s how I’ve currently prioritized security-related scenario investigations:

  • Ensure that Http basic over SSL works without any issues
  • Web API as an AuthN + AuthZ + Resource server – this would make the Web API equivalent to a service like Twitter where you could enable users to authorize 3rd party applications to your Web API (along with manage the permissions of those applications) – the key here is that Web API would have manage its own credential store.
  • Web API as an AuthZ + Resource server – this is similar to the previous with the notable exception that Web API would rely on a federated identity provider for AuthN.  In this scenario, we would integrate with an STS (or broker like ACS).

Do these look like the right scenarios?  The right ordering?  As with everything else, I welcome your feedback!

About Howard Dierking

I like technology...a lot...
This entry was posted in OAuth, Uncategorized, Web API. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • AdamBaldwin

    I’d love to see a multi-provider sample as well. You could probably take advantage of returning mutliple www-authenticate header in the response (??) and the client could display links to each “realm/location”. I’m not sure what the best practice is for this, according to the spec….

  • Adro

    Thanks, Howard. I have opted for a browser approach, since my users authenticate with facebook with the javascript sdk prior to making calls to my API. I’m using a message handler to validate the sent token against facebook and set the authorized identity (httpcontext.current.user) there.

  • howarddierking

    because in this case, my server application (the Web API) was the application accessing Facebook – not the browser. As such, from an OAuth perspective, the user is authorizing my Web API and that is why there’s the extra complexity. I believe that there is an OAuth flow that would account for storing the AT on the browser – however, in this design, I don’t want the browser maintaining the AT.

  • AdRo

    This all seems over-engineered. Why not just pass the facebook access token as, say, a header value in every ajax request and have an action filter check the validity of the token on every call?

  • Pingback: WebApi authorization filter with token in json payload | PHP Developer Resource

  • Anonymous

    Hi Jeremy – yea – it wasn’t too long after writing this post that I moved on to a different team and stopped prototyping the OAuth scenarios. I know that the team is still investigating this scenario – follow 
    http://blogs.msdn.com/b/henrikn/ for updates as they emerge.

  • Jeremy

    Howard,  This discribes a scenario that we are trying to accomplish as well.  We have a similar implementation in strait WCF services, but we would like to move towards the Web API with OAuth approach.  Please let us know if you’ve made any progress prototyping this since it was posted a number of months ago.  We would be happy to provide feedback on any solutions.

  • JD

    Hi great post – just wondered whether this could now be simplified using EasyOAuth Framework now on Codeplex: 
    http://easyoauth.codeplex.com

  • Radenko

    Hi Howard. Thanks for your response . After long investigation I have decided to implement my own OAuth 2.0 server to protect my WCF Web Api and to build fb and twitter login using your approach.

    It would be nice to extend your example to support multi-providers .
    I have found open source project OAuth 1.0a server in ASP.Net MVC   which will be good starting point for me.

    Security is very important part of WCF Web api for me and I hope Microsoft will invest more effort and publish more samples about this subject.

    Again thanks for advices and links.

  • Anonymous

    the multi-provider problem is interesting – will need to think a bit more about that one.  In the meantime, the source code can be found at http://wcf.codeplex.com/SourceControl/changeset/view/66aa503c963c

    look at the path: /WCFWebApi/Samples/Scenario/SecureServices

  • Anonymous

    looks like there may be something here?

    http://oauth.googlecode.com/svn/code/javascript/

  • Radenko

    Hi this is very interesting post. I am trying to make WCF Web API service
    that accept Facebook, Twitter and custom login.
    Custom login also need to works by generating token . (I think I cannot use here OAuth but need to build custom Authorization server) I have planned to use
    FormsAuthenticationTicket for this.I will also have ASP.NET MVC3 web site that will call WCF Web API service.Can you point me to source code from this blog post and comment my approach ?Thanks very much for your help.

  • Luís Carlos Calado Lameirão Go

    Hi Howard,

    I would like to use OAuth 2.0 with Google Prediction API. I have it in PHP but since I want to use Chrome Extensions, I have to do it in Javascript. Can you help me with this?

  • http://www.facebook.com/people/Kevin-Davie/1353257071 Kevin Davie

    congratulations!

  • – –

    At the moment I have a webapp which offers username/password login or
    login via Twitter OAuth. I want to add a REST API for this
    application. Users can login via HTTP authentication AND/OR OAuth:Inspired by your great post I created a sample flow: http://i.stack.imgur.com/EM446.png
    Can this work?

  • Anonymous

    ok – just updated Codeplex to move the OAuth sample out of HttpEnhancements and into its very own end-to-end sample project called SecureServices (http://wcf.codeplex.com/SourceControl/changeset/changes/9f94d015f305).  It’s on the WebAPI-Prototype branch, under the samples folder.  Please let me know if you have any questions or run into any issues.

  • Anonymous

    Will do within a week – was planning to do this week but we had a baby on Wednesday, so that’s set me back a few days :)

  • http://twitter.com/RobGibbens RobGibbens

    This is exactly what I was looking for.  Like Alan, I was looking for a more complete end to end example, as I’m just getting started using the Web Api.  Do you happen to have an estimate of when that might be wired up?  Thanks for this code and post; it’s very helpful.

  • Pingback: DelegatingHandler vs HttpOperationHandler – WCF Web API - Windows Azure Blog

  • Anonymous

    I see – let me wire it into part of contact manager to show how it wires up.  In the meantime, the RegisterOAuth extension method will wire up the op handler and message handler.

  • http://netcave.org Alan Stevens

    Hmmm… I thought there would be a complete sample leveraging the MessageHandler, OperationHandler and Helpers.

  • Anonymous
  • http://netcave.org Alan Stevens

    Hi Howard,

    What’s the ETA of getting this sample in the Prototype branch? I want to pick this apart.

    The first two of your bullet points are very high priority for me. I’m glad that you are working on it. Please reach out to me if you want some early feedback.

    Cheers,

    ++Alan

  • Ineedadip

    You guys are describing my exact scenario, just more eloquently.  This is something we have been kicking around internally.  Let me know if you need any beta testers.

  • Anonymous

    this actually sounds like a great example of bullet #2.  In this scenario, your mobile client would ask the user to authorize it to the his/her protected resources in your REST api.  Your Web API would support (via plugin) the OAuth auth server role which would enable your end users to authenticate to it using Http basic and then authorize the mobile app – at which point, the mobile app would get an access token which it would pass to the Web API on subsequent calls.  Because the Web API implements both the auth server and resource server roles, the token can be cracked open and the IPrincipal can be attached to the thread context, so that you can use it just like any other principal-based scenario.

    Does this sound about right?  As we’re prototyping this scenario out, I would love to keep in touch so that you can verify if the work we’re doing will work for your scenario.  Send me an email at howard at microsoft dot com.

  • John Waters

    Actually, I have a scenario which I believe is quite common. I have a variety of mobile devices connecting to the REST api I am building on WebAPI, including iOS, Android and Windows Phone. I want to use Basic Auth for the initial log in, but then I want to send back some token that is stored on the device and used for subsequent calls. I have a prototype working but it feels pretty clunky, I would love to see some strong support for this scenario in the API. I would like to be able to just plug in code that does the login check for both the username/password and the token, and that returns the initial token, and have the rest be boilerplate. I would also like access to the current caller in my operations. If you want to discuss my current code base I would be happy to share.

  • Ineedadip

    We are not using ASP.NET Membership, but as long as that is abstracted away as much as possible I’m sure we’ll find it useful.  

    API Keys (GUIDS) that our clients can generate is how the API is currently used.  We would like to provide another option for third parties so that they can do some fancy “OAuth stuff” and provide our clients with an option to put in their credentials (Username and Password) to grant authority.

    Just to reiterate, right now third parties have to say “Go into your account, generate an API Key, then paste it here so we can access your account”.  We’d like to go the OAuth route so that clients don’t have to know about/generate/paste API Keys.

    Hopefully some of that makes sense.  Great posts by the way.

  • Anonymous

    Just so that I’m clear on your scenario, are you imagining that your clients would authenticate using their existing keys and then authorize 3rd party applications to access their protected resources in your RESTful API?  I think that’s what I’m reading, but just want to make sure I’m not missing anything.

    I’m planning to approach this using the ASP.NET membership provider as a baseline credential store – do you see any issues with this approach for your scenario?

  • Anonymous

    At the moment, this scenario works if you’re using Windows credentials.  There some ways to get around this (they are different between IIS hosted and self-hosted) but we’re working on making it much more straightforward.  More to come on that topic.

  • John Waters

    Cool, I am also looking to do Basic Auth using a MessageHandler, do you have any code examples for that?

  • Ineedadip

    Exciting, I’ve had great success with the WCF Web API.  We’ve provided a great RESTful API for our clients using API Keys (GUIDs) that are passed as a header, querystring, or using Basic Authentication.  But now third parties want to build applications and nobody likes the idea of generating more API Keys to cut and paste… Everyone is asking if/when we can have some kind of OAuth Implementation.  I hope your second bullet point at the bottom provides some guidance. 

    Great article.