Owin Authentication series
Owin is the next hot thing that everyone (or at least those following the bleeding edge of .NET development) is talking about. When creating a new ASP.NET project it references Owin for the ASP.NET Identity authentication system so it’s obviously not only a hype but actively used. But what is it really and why should I care?
What is this Owin thing?
TL;DR;
Owin is the under the hood interface between web servers and web applications. If you only write web applications in a single framework (such as ASP.NET MVC) an only run on one server platform (Windows with IIS) you can ignore Owin. But it will change the development and deployment landscape for ASP.NET so total ignorance can be risky.
The Complete Story
Owin is a new standardised interface between web servers and web applications. It is meant as a away to break up the tight coupling between ASP.NET and IIS. With IIS supporting Owin it is possible to run other Owin-enabled frameworks such as Nancy on IIS. With Microsoft’s web frameworks depending on Owin and not IIS it is possible to run those in other environments, such as self hosting within a process or on a web server on linux running Mono. SignalR and Web API already uses Owin which means that they can be self hosted and other cool stuff. ASP.NET MVC6 which is part of ASP.NET vNext will be completely based on Owin.
That’s all nice theory, but what does the code look like?
At the core, Owin is really simple. the Owin.dll
contains a single interface, IAppBuilder
.
namespace Owin { public interface IAppBuilder { IDictionary<string, object> Properties { get; } object Build(Type returnType); IAppBuilder New(); IAppBuilder Use(object middleware, params object[] args); } } |
The core function that is of interest to an application developer is Use()
which tells Owin what middleware to use in the http pipeline. Just call Use()
to register middleware and we’re all set running.
That looks simple. Please show an example.
Sure, here’s a small one.
// Somewhere earlier using AppFunc = Func<IDictionary<string, object>, Task>; // Inside a method. using (WebApp.Start("http://localhost:4242", (app) => { app.Use(new Func<AppFunc, AppFunc>(next => (async context => { if(context["owin.RequestPath"] as string == "/") { using (var writer = new StreamWriter(context["owin.ResponseBody"] as Stream)) { await writer.WriteAsync("Hello World!"); } } else { await next.Invoke(context); } }))); })) { Console.ReadKey(); } |
Ouch, that’s a lot of lambdas, can you please explain?
Sure, I’ll make a try. The Owin pipeline construction is not that hard, once you understand that what you see is a factory factory. Instead of using a set of nested lambdas, I created another version where all is nicely separated.
using AppFunc = Func<IDictionary<string, object>, Task>; class Program { static void Main(string[] args) { using (WebApp.Start("http://localhost:4242", Startup)) { Console.ReadLine(); } } private static void Startup(IAppBuilder app) { // Have to explicitly construct the Func<...> since the argument of // Use() is of type object. app.Use(new Func<AppFunc, AppFunc>(BasicAuthenticationMiddleware)); app.Use(new Func<AppFunc, AppFunc>(StartPageMiddleware)); } private static AppFunc BasicAuthenticationMiddleware(AppFunc next) { return new BasicAuthenticationHandler(next).InvokeAsync; } private static AppFunc StartPageMiddleware(AppFunc next) { return new StartPageHandler(next).InvokeAsync; } } |
The hosting environment takes a Startup
function that is called to set up everything. That function registers a set of Middleware with the application. For each request, the application calls each of the the middleware components with the head pointer of a linked list to an existing set of handlers. Each middleware can add one or more handlers to the request handling pipeline by returning a reference to the handler that will be the new head of the list. Each handler is responsible for remembering and invoking the next handler in the list.
The handler is a delegate with signature Func<IDictionary<string, object>, Task>;
, most often abbreviated to AppFunc
through using AppFunc = Func<IDictionary<string, object>, Task>;
.
The signature of the middleware is Func<AppFunc,AppFunc>
. It takes an AppFunc
that is the current head of the linked list and it returns the new head of the list. There are also other ways to add middleware, but for this post, one way is enough.
So all of that previous code is just two layers of indirection to set up things. What do the actual handlers look like?
This is a dummy authentication handler for basic authentication. Don’t use it in production, because it will accept any user name and password.
using AppFunc = Func<IDictionary<string, object>, Task>; class BasicAuthenticationHandler { AppFunc next; public BasicAuthenticationHandler(AppFunc next) { this.next = next; } public async Task InvokeAsync(IDictionary<string, object> context) { if(((IDictionary<string, string[]>)context["owin.RequestHeaders"]).ContainsKey("Authorization")) { await next.Invoke(context); } else { ((IDictionary<string, string[]>)context["owin.ResponseHeaders"])["WWW-Authenticate"] = new string[] { "Basic realm=\"http://localhost\"" }; context["owin.ResponseStatusCode"] = 401; } } } |
At the core, a handler is a Func<IDictionary<string, object>, Task>
. The IDictionary
passed in is the reference to the Owin environment where the current request and response and other things can be found.
The InvokeAsync
method checks if there is an Authorization
header and in that case invokes the next handler in the list. If not, it sets up an authentication challenge and returns without letting the handlers further down the pipeline run.
Since each handler is responsible for invoking the next handler it is possible to add code that runs both before and after call to the next handler.
That made more sense. But it looks awfully low level to use a dictionary and casting for everything.
Yes, you’re right. I deliberately chose to use pure Owin for this example but in real life, some framework is used that takes care of the messy parts. Microsoft’s framework (Microsoft.Owin.*
namespace) is called Katana and is open sourced on codeplex. Katana contains a set of standard middleware for things like authentication, static file serving, logging and the self host I use in the code samples above.
That’s probably nice, but do I have to care?
As an ordinary web application developer you can probably safely ignore Owin for now. If you want to make your application more future proof you can start changing all dependencies to System.Web
(such as HttpContext
) to dependencies on Owin instead.
If you are writing middleware such as authentication modules you should care and make your software an Owin middleware instead of a classic HttpModule.
Ok, I’ll probably just look a little more at this before continuing with the work I should do. Where can I fetch some code to get started?
The code examples for this post are available on https://github.com/AndersAbel/OwinSelfHostTest.
OK, it would be better if there was a demo site using OWIN.
Or, even better, a demo site using OWIN but WITHOUT ANY ORM (like E.F.) and using 100% stored procedures and a custom authentication method (not using the default identity tables in the DB, etc).
That would be helpful. Most people don’t like ORMs and OWIN needs ORM caching SO MUCH !
I like the cut of your jib. No E.F. in the demo.
Who do you keep quoting throughout your post? Is this a re-enactment of an actual conversation you had, or do you have multiple personality disorder?
It’s neither an actual conversation, nor do I have multiple personalities. It is an effect of a time travelling experiment I did, where I talked to a two-month old version of myself where the future version of myself informed my previous self about Owin. ;-)
Simply terrific response to Roger’s (provocative, unless he is a close friend) question. However, to be nit-picky, the ability to talk to two month older instance of yourself is often confused with having multiple personalities :-)
Roger, if you want to nitpick at semantic details, then why arbitrarily choose CSS… why not drill all the way down to HTML? It’s just an HTML paragraph tag, not a blockquote.
The author has written a very informative article. Thanks to Anders!
Thanks Anders, I think this was a very useful post. I had one question though , is the AppFunc Owin’s abstraction on top of a DelegatingHandler ? I mean, would you inject in a AppFunc where you would had previously added a DelegatingHandler? Thanks!
I’ve never used a DelegatingHandler, but it looks like they share the same basic design pattern: Chain of Responsibility. The difference is that it looks like the DelegatingHandler is something used only in special circumstances, while owin’s AppFunc is used all the time. Also, an owin pipeline typically consists of many middleware and in most cases every one of them invoke the next delegate.
When comparing with the old IIS pipeline, I’d say that an owin middleware is more like an http module than a handler.
Thanks for the reply. I am starting to think Owin Middleware is going to be my solution for some http routing i need to do in my solution. I am thinking of intercepting http calls to my local app and forwarding them to a second api. It seems i could do that with an app func , basically interpret the incoming url and call a http request and return from the pipeline with the response from the second api call.
Running the samples is interesting, but I’m trying to get a clearer understanding of how Owin works with a website that will eventually run in IIS. We have questions about how recycling the AppPool changes when using Owin. Can you recommend any good reads on that topic?
It’s an interesting question, but unfortunately I don’t have any resources to recommend on IIS hosting.
I’d recommend posting a question on Stack Overflow. Please post a link here to the question so that others reading the comment can follow.
Appreciate the article but to me it all seems too much like a solution to a problem nobody had. We’ve had a lot of those in the past decade or so.
Are you kidding? This lets .NET ASP.NET code be hosted on Linux or Mac OS X.
This is huge.
And Anders did a great job informing us on its capabilities.
If you want a further information and how OWIN relates to other ASP.NET capabilities, I suggest you read the book “Designing Evolvable Web APIs with ASP.NET” by Glenn Block and Pablo Cibraro.
Okay.. just to play along, you can host an ASP.NET application on Linux or on a Mac, okay fine. But that seems like a niche scenario to me. From a corporate IT perspective that’s a complete non starter. In terms of the start up and independent space, if you’re willing to bet your concept and funding on ASP.NET on MacOS as your operating environment… you’re asking for it. Seems like you folks have trouble separating need vs want.
Think of this though, you could create a .NET web site and run it not only on a corporate IIS server but could push it to a cloud platform like Amazon or Google which primarily use linux servers that are OWIN capable. Also if you need a site that may experience high traffic or transactions, IIS is going to kill you. But with a OWIN enabled web site you could simply push it to a faster leaner server platform that can handle it. This is actually a huge thing.
Anders, Well done. This post is great
This seems just like more useless bloat nobody is ever going to need that is polluting the .NET eco-system. Like much the ASP.NET MVC guys have been doing the last couple of years. Way too much bloat and feature creep as can also be witnessed with each iteration of Visual Studio which keeps getting fatter, bloatier and slower with ever release.
Stumbled on this because Google indexed the comment on DelegatingHandlers. Some of these comments are extremely short-sighted and myopic in view. I’ve been running MVC via Mono on Linux for years now. I also happen to work with both Azure ( web roles are the relevant thing here ) and Linux servers running on Amazon which run Web API applications. Both of those platforms are now using Owin.
Setting linux aside, for those who don’t grasp its enterprise power, the use of Owin-enabled web roles on Azure presents tremendous benefits, not the least of which is not needing IIS’s heavy-weight. These applications are handling thousands of requests per hour to feed a complex data analysis platform of a very successful company. So, yeah, you can do enterprise grade work with it, even on Linux.
Further examples: Osiris’s recommendation on the API book provides great stuff in support of Owin. That book is excellent.
TL;DR;
Combining OWIN with Visual Studio Code, Asp.Net Core (Previously Asp.Net 5), json configuration files, Gulp, npm, Bower and other such powerful tools that have been used by “Those Non-Windows Platform Developers” is bringing the brains from all sides of the development community to a common set of technologies that will work and perform equally on platforms that currently take no advantage of the Asp.Net stack.
If you are okay with what you are using today, like some classic ASP (Ugh!) developers were saying when that difficult. aspx came out and those aspx developers that did not want to move to MVC and those .cshtml and .vbhtml files and that awful Razor stuff, then just stay with what you are using now and let us crazies move forward.
Will be spending some time to try and figure this OWIN authentication out. I have seen a few posts on a few websites but few have been able to demonstrate with a sample the crux of OWIN authentication.
Maybe its too big to cover in a single post but in one sentence explain What does it do? Where to use it? What are the sequence of steps?
OWIN comes build into asp.net mvc projects but again it is surrounded by fluff and other frameworks – show me the heart.
As usual, we will ignore any new MS bloatware until it becomes both mandatory and wrung-out. This “technology” isn’t even close to that level. Silverlight anyone? DCOM? ATL/MFC? All of these ‘technologies’ were New and Exciting for a couple of years, and then abandoned – along with the countless hours spent getting over the learning curve for each of them. All for naught. We have a Roll-Your-Own, Own What You Roll mentality that serves us VERY well, and we don’t plan to break from that. When your business depends on the code you write and deploy, you will understand. No one ever made a nickle from adding dependencies to otherwise working code. Not ever. If we re-deploy our web app(s) to non-MS servers, it will be a clean rewrite, and it will be One-And-Done. Because we will never look back at MS for our servers again. Until then, we have no reason to change.