Friday, February 19, 2010

Developing on Windows 7: ASP.NET Security in IIS 7

I've recently gotten a new development machine at work. I've been using a laptop with a 1.8GHz dual core Centrino, 2 gigs of RAM and Windows XP Pro x86. After months of pushing, I finally got them to get us secondary machines. So in addition to the laptop which is now just an "office productivity" machine (i.e. Outlook and surfing YouTube ;-) I now do my development on a desktop with a 2.9GHz Core2 Duo, 8 gigs of RAM and Windows 7 Pro x64. (A bit of an improvement.)

As I explore the transition to Windows 7 I'm discovering the nuances of developing on a 64 bit platform and running ASP.NET sites in IIS7. Fortunately, the move to 64 bits has been a non issue as suggested by Brian Peek in his DotNet Rocks interview. IIS7 has been a bit more of a change.

Apart from the significant change to the administrative console for IIS 7 there are some aspects of it that introduce so new behaviors when running ASP.NET applications. I'm no expert of IIS, but I know that the jump from IIS 6 to 7 has brought in a much higher level of .NET integration. .NET is really a first class citizen in the world of IIS 7 much like it is in Windows 7 all around.

I typically run the sites I'm developing in IIS instead of the built in Visual Studio web server so I can more accurately reflect the eventual environment on which the sites will run in testing and production. Notably, the influences of security of the IIS service compared to running the local dev web server process under my highly privileged user account. I've answered more than one forum post asking why a site can't write to a file resource when it's deployed to the web hosting environment running a standard IIS process. For that reason I almost always make the change to hosting a developing site in IIS when I first create a new web application project.

While developing a new site using the MVC framework I activated web forms security to set up the login. After refreshing the browser all my styles were gone! Being new to MVC I figured I was doing something wrong. However, I was using the MVC's template login page, master page and CSS file so I didn't think that I had messed anything up. A quick "view-source" and click on the referenced CSS file brought me back to the login page. At that point I realized that the CSS file was being blocked by the web forms security settings. A few bounces around my head between "wait a minute, CSS files aren't served by the ASP.NET process" to "this is acting like the dev web server" to "oh yeah, Win 7 == IIS 7 and IIS 7 has way more .NET baked into it."

With the higher level of .NET integration in IIS 7 comes the full scrutiny of a given web applications security settings. So the authorization rules I activated in the application's web.config now are affecting any file served from that web, regardless of whether it's being processed by the ASP.NET runtime. In this case the entire application was denied for un-authenticated users, thus the CSS file request was redirecting to the logon page.

A simple solution is to put all your non-protected content files (css, images, possibly JS) in a directory that contains a secondary web.config that overrides the main config's security:
<?xml version="1.0"?>
<allow users="*" />

This will allow unauthenticated users access to resources in the directory (and child directories) this file lives in.