Over the last couple of days I’ve been getting a couple of questions regarding Authentication in the West Wind West Wind Web Store application for the access to the Admin section of the store. In the store I have an admin directory set up that by default is secured with Windows authentication.

 

Whenever I can in my own applications I try to use Windows Auth because frankly it’s an easy way for admin functionality to be accessed. It’s easy to deal with assignment of rights and you get a lot of control over which resources you protected. That works fine if you have an internal app or an app with a few administrators. My philosophy here is simply this: If you need to set and manage a few users independently of your application then you might as well use Windows for this because it provides an easy and most flexible way to provide access to your application. I realize this is not always possible due to IT or ISP policies, but when it is easily the most painless solution I can think of...

 

Contrast this with Forms Authentication in ASP.NET which for many seems to be the answer to all security questions <g>. But I have a number of issues with Forms Authentication that have made me reluctant to use them:

 

  1. Lack of granularity
    You assign Forms Authentication on a per directory level and you can’t control access on a file level with it. It's an all or nothing approach.

  2. Protects only ASP.NET resources
    Forms Auth only works against ASP.NET managed resources – basically anything that is mapped back to the ASP.NET ISAPI extension via script map. So any static content you might have in a directory is not protected. If you have things like static XML files, config files of your own, logs etc that all may go unprotected unless you map those extensions to an ASP.NET handler (like the ForbiddenHandler).

  3. Doesn’t work with Web Services or other low level HTTP clients
    You can’t use Forms Authentication with Web Services because Forms Authentication basically is a custom HTML based security implementation. There’s no protocol that can be navigated for an HTTP handler so if you want a Web Service secured that’s a no go.

 

Forms Auth seems like a great solution for Intranet applications or applications that have fairly simple needs for locking down sections of an application, but for me at least I see these limitations as not worth the ‘built-in’ benefit that they provide.

 

What would be really useful for #3 is that Forms Auth could automatically implement Basic Authentication under the covers – not Windows based Basic Auth but custom Basic Auth that validates against your own data. If you turn off Basic Auth on the Web Server Basic Auth requests are forwarded directly to ASP.NET and the Basic Auth protocol is fairly trivial to implement and Browsers already know how to display these dialogs. The advantage is that you could remove the login dialog page and get the stock login dialog instead in the browser or allow navigation with any kind of HTTP client including non-visual ones like HttpWebRequest or a Web Service client.

 

I've done this before with a custom module, but it'd be really nice if Forms Auth would support that directly.

 

So what do I normally do? I find that in most of my applications, Forms Auth is just not a good fit. Either the apps are small enough that Windows Auth works fine in the situations where I would possibly use Forms auth (namely directory based access control – which is all that Forms auth can offer). Or if it’s application centric, I end up with a custom scheme of users that is usually tied to some business entity like a Customer object etc. Interestingly enough ASP.NET 2.0 introduces the new MemberShip Provider interface and while that makes perfect sense if you have an app that just needs security that’s independent of the actual business operation, for most real-life apps it strikes me that you’ll rarely have *just* a user file that needs to be managed. Usually it’s an entire profile or customer, or other entity that’s tied in with the login and there’s little need to separate out that information into a separate provider.

 

 

 

 

Anyway, the issue that a couple of people have been having has been that Windows Auth just was not an option for them as the ISP they were hosting with was not allowing access through Windows Auth (hmmm…). So as a quick fix I thought that Forms Auth as a quick and dirty replacement for the directory level admin lockdown is probably the easiest solution to this request.

It’s been a long while since I used Forms Authentication so I quickly sat down and hooked up a Forms Auth interface for the store, which is easy enough to do. It worked if I use custom authentication (ie. call my own login code).

 

But for some reason I couldn’t get Authentication to work against key value pairs in Web.config:

 

<system.web>
    <
authentication mode="Forms">

      <forms loginUrl="login.aspx" timeout="20" >

        <credentials>

          <user name="rstrahl" password="secret" />

          <user name="rick" password="secret" />

        </credentials>

      </forms>

</authentication>

</system.web>

and then applying the Forms Auth in the admin path:

 

  <location path="admin">

    <system.web>

      <identity impersonate="false"/>

 

      <!-- WS: Allow only Authenticated users -->

      <authorization>

        <!-- allow users="*" /-->

        <deny users="?" />

        <allow users="rstrahl,rick" />

      </authorization>

    </system.web>

  </location>

 

The Login.aspx fires just fine when I try to access the Admin path. The login page comes up and I grab the username and password but:

 

protected void btnSubmit_Click(object sender, EventArgs e)

{

    // *** Do custom validation

    // if (this.LoginUser(this.txtUsername.Text, this.txtPassword.Text))

 

    // *** Use Web.Config users

    if (FormsAuthentication.Authenticate(this.txtUsername.Text, this.txtPassword.Text))

    {

        FormsAuthentication.RedirectFromLoginPage(this.txtUsername.Text, false);

    }

 

    this.ErrorDisplay.ShowError("Invalid user name or password.");

 

}

 

The FormsAuthentication.Authenticate() does not return true for a valid username password combo.  This is ASP.NET 2.0 and I’m stumped. It almost looks like ASP.NET is not looking at the Credentials values at all. Am I missing some new flag that needs to be set or something?