ASP.NET http authentication header rewrites

Wed, May 21, 2008 3-minute read

I were recently a victim of asp.net's browser detection and on the fly content change.

The story is:

I work for a company called ZYB, and for a new feature we are developing we have created some HttpModules, which basically provides means of authenticating our users against their usual ZYB account using either Bacic Authentication or Digest Authentication.

This is all fine, and since both Basic Authentication and Digest Authentication are pretty straightforward to implement we were done in a few days.

We tested the modules, simply by invoking the urls that were protected by the web.config sections:

<authorization>
<deny users="?" />
</authorization>
<authentication mode="None" />

Please note that when developing your own authentication modules, you have to allow Anonymous users in IIS, and remove all other authentication options, and in the web.config, you have to set the

<authentication mode="None" />

Otherwise your modules wont kick in.

But back on track, this is not the reason why I am writing this blog post, its simply because we suddenly discovered that for some user agents, asp.net was modifying the HTTP 401 Unauthorized status code to 200 OK, but still sent the WWW-Authenticate header anyway.

This does seem like a bug, and I traveled many paths before finding out that it was the user-agent header that triggered the Status rewrite.

I am pretty sure asp.net should never rewrite the status codes, at least not for authentication, since it pretty much screws up authentication.

Since changing the User-Agent was not an option, I tried to change the Request headers, but microsoft have made that impossible with a recent fix to .NET.

So I was getting desperate, and I tried to use some of the .browser files you can place in the App_Browsers directory, but I could not find any options for "Do not fuck up my status http headers", so no luck there.

In a desperate measure, I looked at the clientTarget xml elements you can put into the web.config, but no luck there as well, so my last try before rewriting the entire feature, to use in place authentication within the http body, was the

browserCaps section in system.web in the web.config.

I found that if I added the following section:

    <browserCaps>
      <result type="System.Web.HttpBrowserCapabilities"/>
      <use var="HTTP_USER_AGENT"/>
    </browserCaps>

asp.net stopped fucking up my headers, and returned the proper 401 status code.

The user agent that fucked everything up, was more or less any mobile device out there, and ZYB being a mobile company, its damn hard to just ignore that.

So this blog post is hopefully a help for people stuck in the same situation.