Wednesday, December 07, 2005 - Posts

web.config, Windows Authentication, and getting the logged-in user's identity

I've been developing an ASP.NET 2.0 web site on my machine (and I love the in-built web server) which accesses an SQL Server 2000 database through an SQL account, but which also passes the current user's Windows login for row-level access. This works fine in development when the web.config file is set up like:

<authentication mode="Windows"/>

In this situation in development, my Windows login is returned when using code like System.Security.Principal.WindowsIdentity.GetCurrent(), which is what I want.

But, when I tested the deployment of the site on Windows Server 2003, the current user always returned NT AUTHORITY! So, after checking all the possible settings in IIS (and comparing settings to sites I *know* get the current user), I discovered the following on a page of PAG documentation on MSDN:

Impersonation Options

You can use Windows authentication with ASP.NET in a number of ways:

  • Windows authentication without impersonation. This is the default setting. ASP.NET performs operations and accesses resources by using your application's process identity, which by default is the Network Service account on Windows Server 2003.
  • Windows authentication with impersonation. With this approach, you impersonate the authenticated user and use that identity to perform operations and access resources.
  • Windows authentication with fixed-identity impersonation. With this approach, you impersonate a fixed Windows account to access resources using a specific identity. On Windows Server 2003, you should avoid this impersonation approach; instead, use a custom application pool with a custom service identity.

The second option was exactly what I wanted, and can be accomplished by simply adding the following line to web.config (I added it after the "authentication" section):

<identity impersonate="true" />

Problem solved! I hope this might help anyone else in the future...and I know I'm probably going to need to refer back too.

Regular Expression to Prevent Users Entering Malicious (HTML) Form Data

Cross-site scripting (XSS) is a problem that ASP.NET helps you deal with by not allowing any "malicious" (I'm interpreting this as HTML tags, whether it's <0BJECT> or <i>) input in the Request object, by default. This behaviour can be switched off by setting the "ValidateRequest" Page directive to "false" and you can do your own validation à la Peter van Ooijen's "Protecting an ASP.NET page against malicious input with ValidateRequest (A potentially dangerous Request.Form value was detected)" post.

In my case I left the default setting on - I'm not good enough to catch all possible vectors of attack - but used a RegularExpressionValidator validation control, with a regular expression of "^[^<>]+$" (without the quotes) to detect if there are any angle brackets in the field. For later-version browsers, the validation controls are rendered as client-side Javascript which could possibly be bypassed, but that doesn't worry me because ASP.NET also handles the problem server-side and if malicious text did make it to the server, a System.Web.HttpRequestValidationException exception is raised which I handle through my error page.

The validation control merely forewarns the user and in my mind is enough to prevent accidental or curious users from entering HTML tags in free-text data entry fields.

Note: I figured out the regex using http://www.regular-expressions.info/reference.html - the regex matches strings from start to end (the first ^ character and closing dollar sign) where there are no occurences of the characters in the square brackets. Initially I thought that the angle bracket characters would need to be escaped, but they don't.