Host authentication and Web API with OWIN and active vs. passive authentication middleware
A quick note about Web API 2 security running in OWIN and a ASP.NET project (which you will see with the new templates in Visual Studio 2013). By default, Web API code running in a host will inherit the host’s authentication model. This means if the web application uses cookie authentication or windows authentication for the HTML portion of the application, then when Ajax calls are made from these web pages back to the server this same authentication will be passed along to calls into Web API.
RequestContext.Principal
Before I even get into the main part of this post, a side note on the identity of the calling user: Web API 2 introduced a new RequestContext class that contains a Principal property. This is now the proper location to look for the identity of the caller. This replaces the prior mechanisms of Thread.CurrentPrincipal and/or HttpContext.User. This is also what you would assign to if you are writing code to authenticate the caller in Web API.
SuppressDefaultHostAuthentication
While the MVC templates use a cookie based authentication mechanism, the new SPA templates prefer to use a token based authentication model explicitly passed via the Authorization HTTP header (which is better since it avoids CSRF attacks). This means that the default authentication from the host must be ignored since the authentication will be performed against something else other than a cookie. Web API 2 added a feature to ignore the host level authentication called SuppressDefaultHostAuthentication. This is an extension method on the HttpConfiguration that adds a message handler. The purpose of this message handler is to simply (and explicitly) assign an anonymous principal to the RequestContext’s Principal property. This way if cookie middleware does process an incoming cookie, by the time the call arrives at Web API the caller will be treated as anonymous.
Authentication filters
So then how will Web API code authenticate the caller? Well, in Web API 2 a new filter was added: AuthenticationFilter. This is a dedicated stage in the Web API pipeline for inspecting and authenticating the HTTP request. You can write your own, or you can use the new built-in HostAuthenticationFilter. The name of this new authentication filter sounds like a misnomer — we just suppressed the host authentication with with the SuppressDefaultHostAuthentication extension method — why are we now trying to authenticate form the host? Well, the HostAuthenticationFilter accepts a constructor parameter indicating which type of authentication we will use from the host. In the SPA templates they use one called “Bearer” (which is different than cookie).
The reason Web API is deferring back out to the host is because of the move to OWIN authentication middleware. OWIN authentication middleware is providing a generic and host independent framework for authentication. This same OWIN authentication middleware could also be used to authenticate calls into SignalR or Nancy. This makes more sense than Web API building their own custom authentication framework that would only work in Web API.
Active vs Passive authentication middleware
One question that arises — if the new templates have multiple OWIN authentication middleware configured, then which one is really used? Well, OWIN authentication middleware has the concept of passive vs. active. Active middleware always look at every incoming request and attempt to authenticate the call and if successful they create a principal that represents the current user and assign that principal to the hosting environment. Passive middleware, on the other hand, only inspects the request when asked to. In the case of the default templates from Visual Studio 2013, all the middleware configured are all passive by default, except for the “main” cookie authentication middleware (turns out there are two cookie middlewares that get used in some templates — the main one and another one for external identity providers and this other one is marked as passive).
All together now
So then in Web API when you use the HostAuthenticationFilter, you’re normally using it with a passive OWIN authentication middleware. When the authentication filter runs, it explicitly asks the OWIN authentication middleware to run and determine the identity of the caller. If successful, the result is populated into the RequestContext.Principal.
HTH
Trackbacks
- Dissecting the Web API Individual Accounts Template–Part 2: Local Accounts | www.leastprivilege.com
- A primer on external login providers (social logins) with OWIN/Katana authentication middleware | brockallen
- [Dev Tip] Secure a Web API with Individual Accounts and Local Login | sudo man
- L’authentification WS-Federation avec Azure Windows Active Directory | Nouvelles Chroniques d'Amethyste
>>use a token based authentication model passed via the Authorization HTTP header (which is better since it avoids CSRF attacks
AFAIK, this is not correct. Authorization Header is vulnerable to CSRF attack, http://www.asp.net/web-api/overview/security/basic-authentication
What is vulnerable is implicit passing by the browser. This is true for cookie and basic auth and windows auth — any time the browser implicitly passes credentials, CSRF is an issue. When writing JS and explicitly passing an authorization header this is not an issue. It is certainly subtle.
Updated to “explicitly passed via the Authorization header” for clarification. :)
Where can I find a simple example of what you just described here? I don’t want to use an external authn provider, I’m happy to roll my own, but can’t find a simple example using Owin/Katana. Even Katana doesn’t have a sample of this (or much of anything else, for that matter ;) ).
Are the templates in VS2013 not sufficient? I don’t have any samples of my own to share, so sorry.
Is it possible (using HostAuthenticationFilter) for a web api to support NTLM and Bearer token at same time? We have many existing API’s which use NTLM (intranet). We’d like to move away from this, and use OAuth going forward – to support a broader user base (partners etc).
It gets very complicated to support multiple authentication types at one endpoint. This is one huge benefit of using a token service — to abstract that out. And given that NTLM is IIS based and token is middleware based this adds to the complexity.
How would the HostAuthenticationFilter know from where to get the token?
My problem: I am using a ASP .NET app and using owin authentication. I also have some API controllers which i am calling using AJAX, but I get a 401 error if i add the Authorize attribute and if i remove it and try to check if the user is authencated using requestcontext I get that NULL. What should i do?
It doesn’t — it calls into the matching authentication middleware and it’s the job of that middleware to find and validate the token.