The Web API v2 OAuth2 Authorization Server Middleware–Is it worth it?

Adding the concept of an authorization server to your web APIs is the recommended architecture for managing authentication and authorization. But writing such a service from scratch is not an easy task.

To simplify that, Microsoft included an OAuth2 based authorization server “toolkit” as part of the Katana project, which is also used in the standard Web API templates that ship with Visual Studio 2013. I get a lot of questions about how this middleware works, whether I like it, what the limitations are and if I would use it at all. To make this discussion easier in the future – here’s my take.

What I like
Microsoft’s intentions were really noble – they tried to make it very easy for the “average” (read: not security expert) developer to do the right thing – namely push them to an architecture where authentication and authorization decisions can be abstracted away into a separate “component” while using a standard protocol (OAuth2). This would result in token-based authentication in general – and would also get rid of the cookie and CSRF problems for SPAs in particular. The pit of success so to speak.

The middleware produces encrypted and signed tokens (protected with the usual machine key mechanism) which can be automatically consumed by the corresponding token middleware, creates separate endpoints,  forces you to at least think about client validation and requires SSL by default.

The two most common flows I see for Web API clients is resource owner flow and implicit flow. Resource owner flow is now very easy to implement with the new AS middleware. It really just takes a few lines of code and you are done. I like that a lot (if resource owner flow is the right architecture for you – which is a different discussion). I wrote about the implementation here.

The same applies to client credentials flow (not so common), and custom grant types (even less common).

What I don’t like
If you want to do anything beyond what I described so far, the complexity increases unproportionally – e.g. adding a “simple” extension to resource owner flow – namely the concept of refresh tokens, suddenly forces you to understand OAuth2 (see here) and the security implications around it. You also have to implement persistence yourself – which on its own is challenging if you would follow security best practices and the OAuth2 threat model. No pit of success.

Another example is implicit flow, which is often the more appropriate flow for native or JS based applications. Unfortunately the middleware implementation is riddled by the fact there is no Katana or Web API based view engine yet, which means you need to use an additional framework when you want to render proper login or consent screens. Scattering the logic of the flow between views, controllers and middleware providers doesn’t make it more intuitive. And when you made it that far, it seems some parts of the protocol are just missing – like returning proper errors from the UI.

In other words – the middleware forces you to understand the underlying protocol, forces you to understand the middleware itself and all its various callbacks and extensibility points, makes you implement the hard (and security related) things yourself, and in the end you have to live with the restrictions that the thin abstraction imposes on you.

Next is documentation – the built-in templates don’t do a very good job of isolating the features and trade-offs of the middleware. They combine all the new concepts of Katana, OWIN, OAuth2 and ASP.NET identity into a hard to follow sample “application”. It took me three blog posts (see here) to describe how the “Individual Accounts” sample works – and I am sure I missed some of the subtleties.

Just recently Microsoft released this very long article that describes all the aspects of the OAuth2 middleware – read it here. It’s good that this document finally exists, but I am not a huge fan of this disclaimer – after you followed the 83 easy steps:

Note: This outline should not be intended to be used for creating a secure production app. This tutorial is intended to provide only an outline on how to implement an OAuth 2.0 Authorization Server using OWIN OAuth middleware.

What would I like to see instead?
Well – it is always easy to bitch and moan about other people’s work – but I was actually asked for feedback during the development of the middleware – and this is just a repeat of what I said back then.

OAuth2 is not the most straightforward protocol to implement – but it is also not too hard. When you start working on it, you realize that the “protocol aspects” of it – like query string formats or response message layouts are actually the easiest part. The hard part is state management, secure data storage, input validation etc. And my main point of criticism is, that the middleware does not help you in any way with that. It simply implements a framework that exposes a developer to a limited subset of OAuth2 without really understanding the use cases.

Much more useful would have been super easy to use, focused and specific implementations of the two most common flows for Web API apps: resource owner and implicit – including ready to use support for login and consent page, scope handling and refresh tokens. That would have also included a persistence layer and state management. Our OSS project AuthorizationServer e.g. takes care of all that.

So overall I’d conclude with saying – even when the intentions were good – the whole authorization server middleware project was a little over ambitious and I can’t really recommend using it (besides for the most simplest cases).

This entry was posted in AuthorizationServer, IdentityServer, Katana, OAuth, OWIN, WebAPI. Bookmark the permalink.

9 Responses to The Web API v2 OAuth2 Authorization Server Middleware–Is it worth it?

  1. Guru says:

    Do you mean to say it is not secure to use it? If it suits my needs…

    • Well – thats my point. It is as secure as you make it. The middleware does not help you with that (besides the basic features I listed). Make sure you read the OAuth2 threat model for the flow you are using.

  2. Dennis says:

    Apologize for being off-topic for this particular post but I was wondering do you have any experience using Authorization Server in conjunction with non-Microsoft Web APIs? Would you recommend something like that?

  3. Pingback: End of Month Research Roundup – February 2014 | endjin blog

  4. JimmyB says:

    Thanks for all the tutorials and videos.

    I do have one question (probably a silly one)
    When we use OWIN Oauth2, where is the ‘Token’ actually saved? in our own DB table or in a separate OWIN server? What is the procedure for checking token to get user details when a user sends a request?

    If it is saved in a separate server , does that mean we have to check with that server to see if the Token is correct for a particular user every time a user sends a request?

    I read lot of tutorials and watched videos but I can’t find these information anywhere

    Thanks

    • Tokens are self contained and signed. The receiver needs to be able to validate the signature (e.g. via the machine key in the microsoft case) – all the information is “inside” the token.

  5. shan_sundaram@yahoo.com says:

    Hi

    Thanks for the detailed article. I have one issue with some of your examples. It may be due to my lack of understanding of how token based authorization works.

    In your sample EmbeddedAuthorizationServer, when I try to run the sample api, I can use fiddler to get the token. That is great. But in your IdentityController, there is an Authorize attribute,but when I try to access the get via browser either chrome or IE or rest clients for chrome like PostMan, even if I didn’t sign in, I can access the resource.I am not getting access denied message. Can you please explain why? With Authorize attribute, I expect it to deny access unless you send the token as part of the header

    Thanks

    • Not sure how you test that – but the Authorize attribute means that there must be an authenticated principal on the request – otherwise you get access denied.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s