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).
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.
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?
As long as they support JWT token. sure.
Pingback: End of Month Research Roundup – February 2014 | endjin blog
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
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.
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
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.
First of all, I haven’t seen anyone with more knowledge than you about this technologies. YOU DA MAN!
uff.. where to start. So, I was reading http://identityserver.github.io/Documentation/docs/overview/mvcGettingStarted.html and… man, i am so overwhelmed. What I am trying to achieve is simple…
I have an app that acts as a central “repository” of “activity logs” for all the users of my application. This is on MVC 5. Basically I force the user to create an account with login and password. In this application they can visualize, edit, etc all of their activities. Also, I want to expose this data to other clients (third party apps), so that the User authorizes this Clients to access their data and add data as well. Think of you creating a Twitter account and allowing other apps to use your tweets, add new ones, etc.
I was trying to find the answer to my problem using your IdentityServer3 but I am more confused now than before.
Should I use Cookie authentication for my MVC 5 application and set up an OAuthServer for my API? OpenID Connect… Is this better than OAuth? I thought I had understood your three parts blogs about dissecting Owin Middleware but when I landed in your IdentityServer3 samples… someone took away the ladder and I was left hanging from the brush!
Sorry for my pseudo-rant but I don’t really know where to start with this.
As you already figured out – what you are trying to achieve is not simple ;)
Not sure what to say – read the intro, watch my talks etc. Don’t expect to understand everything the first time – took me a couple of years.
:) Well, I think my problem is not much about implementing your framework, but which flow applies to my situation. I am not sure if it is correct to split in two (cookies and token) my authentication processes but seems the logical path considering that my web app is not per se a JSClient (SPA). My users shouldn’t have to “authorize” my web app to use their data, so a simple login/password/cookie situation would be sufficient. In the other hand, I MUST setup an authentication mechanism for third parties requesting access to the user data via an API. What would you do in this case?
The getting started walkthrough is actually pretty close to what you are trying to build – MVC app with authentication and Web APIs.
I found this article. I think this could be a good approach. I am going to try to use your IdentityServer using this “configuration”. I’ll let you know how it goes.
Sorry, I forgot the link.
We are beginning the process of implementing OAuth2 in our Web Api environment and have a question regarding tokens issued by the Auth server. When the token is presented to the Resource Server on every request by the client, what, if any validation is performed on the token itself? Is there a NONCE value contained in the token that can be used to detect replay attacks? Also, is there any verification to detect if the token being presented is from a different IP than what it was issued on? Sorry if my questions are junior .. been drinking from the proverbial firehose lately taking it all in. Thx!
Tokens are validated (signature, expiration, audience, scopes etc). There is no replay protocol at the application protocol level – but since SSL is mandatory, this is handled at the transport layer. Everything additional would be an application specific implementation.
Pingback: The State of Security in ASP.NET 5 and MVC 6: OAuth 2.0, OpenID Connect and IdentityServer | leastprivilege.com