Both Forms Authentication and Basic Authentication

The question was asked:

Given an asp.net application that in itself uses Forms Authentication, what is the best practice for securing a public-facing demo site such that nobody who is not in the “in crowd” can see the site at all?

My answer was pretty cool, and I wanted to remember it someday when I had a similar question.  Up-vote it if you too think it’s cool:

Typically the “demo sites” are secured with Basic Authentication.  e.g. return a 401 to the browser with a basic authentication challenge that it turns into prompting for credentials.  In theory, once this is done, the rest of the site is just regular stuff – forms auth when needed.

The difficulty with this approach in ASP.NET comes in the fact that the default FormsAuthenticationProvider is hard-wired to interpret a 401 as “need to 302 to the login page.“  With that as a premise, getting both Forms Authentication and Basic Authentication to happen simultaneously is a challenge.

Also, the Basic Authentication built-in to IIS uses Windows as the authentication store (Active Directory or local windows accounts.)  Getting it to use a different credential store is not easy to do “in the box”.

http://custombasicauth.codeplex.com/ is a project I’ve been watching that is quite intriguing.  It provides a custom Basic Authentication provider that allows you to rig up Basic Authentication from a different provider store.  Pop open the source to http://custombasicauth.codeplex.com/SourceControl/changeset/view/53965#183990 and http://custombasicauth.codeplex.com/SourceControl/changeset/view/53965#183995 and see that they’re just extracting the Base64-encoded header, and comparing it to an ASP.NET Membership Provider.  With that as a premise, you could rig up a similar HttpModule to compare the header data to a user/pass stored in AppSettings, and include the module in your demo site.  The magic sauce is that you don’t set the 401 status on Authenticate, you do so at EndRequest – after the FormsAuthenticationModule has finished it’s “401 to 302 to login page”.  The only down-side is the <location> tags have to be used by Forms Auth or by Basic Auth, but not both.  If the use-case is truly “secure the entire demo site”, then it’s sufficient to code the Basic Auth module to “just do it all”.  I’m about 23 of the way doing exactly this.  When I’m done, I’ll likely post it to GitHub as it’s turning out pretty cool.  Alas, the technique isn’t that hard, and perhaps the description of the solution is sufficient.

And if you really want a hands-off, no-code solution, install http://custombasicauth.codeplex.com/.  It even gives you pretty config windows in IIS.  :D