Catching the System.Web/Owin Cookie Monster

CookieMonster-SittingCookies set through the Owin API sometimes mysteriously disappear. The problem is that deep within System.Web, there has been a cookie monster sleeping since the dawn of time (well, at least since .NET and System.Web was released). The monster has been sleeping for all this time, but now, with the new times arriving with Owin, the monster is awake. Being starved from the long sleep, it eats cookies set through the Owin API for breakfast. Even if the cookies are properly set, they are eaten by the monster before the Set-Cookie headers are sent out to the client browser. This typically results in heisenbugs affecting sign in and sign out functionality.

TL;DR

The problem is that System.Web has its own master source of cookie information and that isn’t the Set-Cookie header. Owin only knows about the Set-Cookie header. A workaround is to make sure that any cookies set by Owin are also set in the HttpContext.Current.Response.Cookies collection.

This is exactly what my Kentor.OwinCookieSaver middleware does. It should be added in to the Owin pipeline (typically in Startup.Auth.cs), before any middleware that handles cookies.

app.UseKentorOwinCookieSaver();

The cookie saver middleware preserves cookies set by other middleware. Unfortunately it is not reliable for cookies set by the application code (such as in MVC Actions). The reason is that the System.Web cookie handling code might be run after the application code, but before the middleware. For cookies set by the application code, the workaround by storing a dummy value in the sessions is more safe.

Beware of Uri.ToString()

When working with urls, it’s sometimes better to use the Uri class than to keep the Uri in a simple string. The Uri class helps validate that the format is a valid Uri and helps splitting out the parts of the Uri in a safe manner. But there is a big gotcha in that Uri.ToString() returns an unescaped representation of the Uri.

The contents of this post might sound simple, but they were behind a nasty heisenbug. Every single insight in this post is something that I learned in a very painful way. I hope that reading this post will convey the same insights in a less painful way.

TL;DR; in two lines of code

The entire problem can be expressed in two lines of code.

var uri = new Uri("http://localhost?p1=Value&p2=A%20B%26p3%3DFooled!");
Console.WriteLine("uri.ToString(): " + uri.ToString());

It looks simple and it should be simple, but it isn’t. When running these two lines on the .NET Framework 4 the following output is produced:

http://localhost/?p1=Value&p2=A B&p3=Fooled!

The query string has been decoded in such a way that it looks like there is an extra parameter p3!

When targeting .NET 4.5 however only the space is unescaped. This can be explained as a result of the breaking changes to System.Uri in .NET 4.5. But that is not the whole story. It gets more complicated (and bug prone) because .NET 4.5 is an in place upgrade to .NET 4.0.

What’s this Owin Stuff About?

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.

Leaving C# (for a while) to Try PHP

To fit in as a .NET/C# Dev I should never use the word PHP (except when cursing). But I want to learn, to know more so I decided to give PHP a try. There are numerous of big, wellknown applications written in PHP so it cannot be that bad, can it?

As a matter of fact, my blog is powered by WordPress which is written in PHP. From a user perspective I think that WordPress works fine. The basic functionality for editing and handling posts, comments and images works great. There are themes for customizations and plugins fore extensions. So I decided that it was time to dive in under the hood and learn more about WordPress and PHP.

In this post I will focus on PHP as a language and platform and skip over the WordPress details.

An Open Source ASP.NET SAML2 Service Provider

I’m happy to announce an open source ASP.NET SAML2 Service Provider. SAML2 is a common standard for single sign on in enterprise environments. A Service Provider in SAML2 is a web site that allows log on through SAML2 Identity Provider (IdP). Implementing a Service Provider requires issuing authentication requests (AuthnRequest) and handling the returned response.

Please check the Kentor.AuthServices tag for the latest posts and news. The information in this post is quite old and mostly outdated.

At Kentor we have seen an increase in the demand for using SAML2 authentication from our customers. When doing a recent project we didn’t find any suitable component, so we had to roll our own. Knowing that we would need to do this more times for other applications we decided to write a more general, standalone component that we can reuse in other projects. We are now also releasing it as open source for anyone to use for free.

The Kentor.AuthServices Library

The library is hosted at github and is released under an LGPL license. We chose that license because while it should be possible to use the library in closed source and commercial solutions, we want the library itself and any improvements to it to remain open source.

The core part of the library is the Saml2AuthenticationModule IIS module that handles the authentication. In the most simple case, it is possible to add the IIS module to configuration and get federated authentication without a single line of code to write. There is a sample ASP.NET MVC application available that uses the library and shows how to call it.

The library is available on NuGet and can be installed with the following command.

PM> Install-Package Kentor.AuthServices
Software Development is a Job – Coding is a Passion

I'm Anders Abel, an independent systems architect and developer in Stockholm, Sweden.

profile for Anders Abel at Stack Overflow, Q&A for professional and enthusiast programmers

Code for most posts is available on my GitHub account.

Popular Posts

Archives

Series

Powered by WordPress with the Passion for Coding theme.