IIS Insider - October 2005

By Ken Schaefer, Systems Engineer Consultant, Avanade

IIS Insider

Populating the "Logon_User" Server Variable

Q. I have created a Web application using ASP. I would like to obtain the Windows user account that is accessing my Web site; however with Anonymous Access enabled the "Logon_User" server variable is blank. If I disable anonymous access, my users can�t access my site. What do I need to do?

A. By default, when a Web browser makes a request to a Web server it does not send the user�s credentials (which includes the user�s Windows username). This is how most public Web sites work - users can anonymously access sites without providing their Windows username to the remote Web site.

In order to make the browser send credentials to the server, you will need to disable "Allow Anonymous Access" (there is one exception to this, which I�ll deal with later), and enable one of the other authentication mechanisms such as Basic, Digest or Integrated Windows Authentication.

After you have done this, the exchange between client and server looks a little like Figure 1 below. Since the client is sending a username to IIS, the Logon_User server variable will be populated.

Since IIS 6 is no longer using the configured anonymous user account (by default IUSR_<machinename>) to access resources (for example, to read files off the hard disk or access databases) you will need to ensure that whatever user account your user is supplying has the same permissions as IUSR_<machinename> currently has. This includes granting NTFS Read permissions to ASP files within your Web site, and permitting those accounts access to any other files or databases required by your application. To configure NTFS permissions, right-click your Web application�s root folder in Windows Explorer and choose "Security". Add the necessary user accounts via the "Add" button and give them "Read" permissions. Apply these changes to all subfolders and files. If you have many users, you can speed up the process by creating a Windows group, and add your users into the group. Then you can give the group NTFS Read permissions to the files.

If your users still can not access your application, you will need to troubleshoot the situation to determine the underlying cause. Verify that your users are correctly entering their usernames (including any Domain component) and passwords, that the local security policy on the IIS server (and any applicable Group Policy Objects) allows those users to logon to the server, and that the users have permissions to necessary resources on the server. The Authentication and Authorization Diagnostics (AuthDiag) tool can help your troubleshoot authentication and authorization problems. For IIS 5.x and 6.0, you can download the AuthDiag Tool at: http://www.microsoft.com/downloads/details.aspx?FamilyID=e90fe777-4a21-4066-bd22-b931f7572e9a&DisplayLang=en

The one exception that I mentioned earlier occurs when you have both Anonymous Access and at least one other authentication mechanism enabled and the configured Anonymous User (by default IUSR_<machinename>) does not have NTFS permissions to the file in question. In this case IIS will be unable to use the Anonymous User account to read the file off the hard disk, and instead will prompt the user to supply credentials to be used.

SQL Server - IIS Connections in a Workgroup

Q. I am trying to use a Trusted Connection between my Web application and my back-end SQL Server database. However my two machines are not in a domain, but in a workgroup. The machine running IIS is my Windows XP development machine, and the back-end SQL Server is running on Windows Server 2003. At the moment I am getting an error when attempting to open the connection: "Login failed for user '(null)'. Reason: Not associated with a trusted SQL Server connection." Can this be done?

A. This can be done, even in a workgroup scenario, however the configuration does take a little bit of work, and varies depending on the type of application you are using (for example, classic ASP versus ASP.NET)

However the basic principle remains the same no matter which technology you are using. Windows XP supports "pass-through authentication" (as do Windows NT, Windows 2000, and Windows Server 2003). This allows the user to authenticate to a remote machine using credentials that are valid on the remote machine. In other words, if the username and password you are using on your local machine are the same as the ones on the remote machine, then this authentication process can be transparent to the user.

So, the trick involves creating a user account on the SQL Server that has the same username and password that the Web application on your IIS Server is using. What makes the situation more complex is the ability of Web applications in IIS to either use a fixed user account (or identity) to run the Web application, or to run the Web application using credentials supplied by the browsing user (in the latter case, we say that the Web application is "impersonating the end user"). Typically a fixed identity will be used when we are allowing Anonymous Access to our Web application, and we would impersonate the end user when we require the user to supply credentials. However, just to make things more interesting, ASP.NET does provide functionality that allows the developer to force the user to supply, but not impersonate that end user! Table 1 below helps summarize the possibilities.

Table 1

Possible Scenarios Web Application is ASP based Web Application is ASP.NET based

Web Application allows

The configured Anonymous User

The ASP.NET process identity

Anonymous Access

account (by default IUSR_<IISServerName> will be used. In some cases, discussed below, the IWAM_<IISServerName> account will be used.

will be used. By default, on Windows 2000 and Windows XP, this is the ASPNET account, and on Windows Server 2003 this is the Network Service account.

Web Application requires user to supply Windows credentials

ASP will impersonate the user.

ASP.NET will impersonate the user if the <identity impersonate="true">

option is set in web.config. Otherwise, the ASP.NET process identity will be used.

As you can see, there are a number of possible scenarios. Depending on the scenario, you will need to create different user accounts on the back-end SQL Server.

If you are not allowing Anonymous Access to your Web site (i.e. you are forcing your users to authenticate), and you are impersonating that user account (e.g. using the <identity impersonate="true">

option in ASP.NET) then all you need to do is:
  1. Use Basic Authentication in IIS. This is so that IIS has the username and password in clear text. For security reasons, you should use SSL between the user�s browser and the IIS server to secure the transmission of these credentials

  2. Create Windows accounts on the SQL Server that correspond to your user�s credentials. Give these user accounts appropriate permissions in SQL Server.

If you are not impersonating the end user (for example, you are allowing anonymous authentication), then you must create accounts on the SQL Server that correspond to the fixed accounts used by your Web application. Since IIS is running on Windows XP we�ll cover that first (Windows 2000 is the same as Windows XP). Configuring IIS on Windows Server 2003 requires some slight changes, and those are detailed at the end.

For ASP.NET applications running on Windows 2000 and Windows XP, the fixed identity is the "ASPNET" account by default; and for ASP applications, two accounts are used: IUSR_<machinename> (for ASP pages) and IWAM_<machinename> (for certain events handled in global.asa).

For an ASP.NET application running on a Windows 2000 or Windows XP machine, you must perform the following steps:

  1. On your SQL Server, create a new account called ASPNET. Assign a password to this account. Ensure that the password does not expire, and that the user doesn�t need to change the password at next logon. Assign this account appropriate permissions in SQL Server.

  2. On your IIS Server, open machine.config located at %systemroot%\Microsoft.Net\Framework\v1.1.4322\config. Locate the <processModel> section and edit the password="" attribute. Set the password to be the same password you assigned in step 1 above.

  3. On your IIS Server, open the Computer Management MMC located in your Administrative Tools folder. Locate the ASPNET user in the Users folder. Right-click on this user and choose to reset the password to the same password you assigned in step (a) above

  4. On your IIS Server open the Services MMC located in your Administrative Tools folder. Restart the IIS Admin service

Your ASP.NET applications should now be able to connect to your SQL Server using a trusted connection.

If you are using a classic ASP application running on Windows 2000 or Windows XP, you must perform the following steps:

  1. Identify the account you are using for anonymous access to your Web application. By default this is called IUSR_<IISServerName>. You can determine the account by using the IIS Manager. Open the properties for your Web site or Web application, and on the Directory Security tab click "Edit" under "Anonymous Access and Authentication Control."

  2. Determine the password that this account is currently using. To do that, you can use the WMI script from the January 2002 IIS Insider article. An alternate method of getting this password involves downloading and installing the Metabase Explorer tool (part of the IIS 6.0 Resource Kit Tools) and using the "Show Secure Properties" menu option.

  3. On your SQL Server, create an account with the same name as the anonymous user account your IIS Server is using. Assign the same password that the script in step 2 uncovered, Ensure that the password does not expire, and that the user doesn�t need to change the password at next logon. Assign this account appropriate permissions in SQL Server.

Your ASP application should now be able to connect to your SQL Server using a trusted connection. If you are connecting to the SQL Server in your global.asa file (in certain event handlers such as Session_onEnd), you will need to repeat the steps above for the IWAM_<IISServerName> account, as this account is used when those events are handled. The script mentioned in step 2 above displays the password for the IWAM_<IISServerName> account if you do need to repeat the process.

If your IIS Server is running on Windows Server 2003 in the default Worker Process Isolation mode, then a few steps are different. For ASP.NET applications, you configure a user account by editing the identity for the Web Application Pool that your application is being served in. This is done through the Web Application Pools node in IIS Manager. Because you can not set a password for the default Network Service account, you will need to create a new Windows user account, and assign it the necessary permissions to act as a worker process identity. Microsoft KB Article 821614 details these permissions.

On Windows Server 2003, global.asa events are no longer handled by IWAM_<IISServerName> when running in the default Worker Process Isolation Mode. So, it is not necessary to configure duplicate IWAM_<IISServerName> accounts on your IIS and SQL Server computers.

Using Forms Authentication to Protect Files

Q. Currently we use ASP.NET forms authentication to protect access to our ASP.NET pages. We also have various other files on our site: PDFs, videos and PowerPoint presentations. If a user records the URL of those files, they can download them without having to log on. How can we use Forms Authentication to protect these files?

A. The .NET runtime provides "forms based authentication". When an unauthenticated user requests a protected page, the user can be automatically redirected to a login page. After successfully logging in, they can be taken back to the original page they requested. Authentication status is maintained via cookies, and the .NET Runtime can take care of all necessary cookie management. For more information on Forms Authentication, and how to implement it on your ASP.NET site see the Forms Based Authentication QuickStart Tutorial at GotDotNet.com: http://samples.gotdotnet.com/quickstart/aspplus/default.aspx?url=%2fquickstart%2faspplus%2fdoc%2fformsauth.aspx.

Although Forms Authentication can be quickly implemented for ASP.NET resources, it doesn�t protect non-ASP.NET resources, such as plain HTML files, images, Adobe Acrobat (PDF) documents and so forth. To understand why, we need to look at the IIS and ASP.NET request-processing pipelines.

The processing pipeline is shown in Figure 2, below. An incoming request passed from http.sys (the kernel mode HTTP driver) to IIS. After being processed by any applicable ISAPI Filters, IIS determines whether the request should be processed by an ISAPI Extension. Whether a request is processed by an ISAPI Extension depends on whether the file extension of the requested resource is mapped to an ISAPI Extension in the IIS Metabase. If there is no mapping, the request is handled by the Static File Handler (indicated by the number 1 in the diagram). This is what happens to requests for static files such as HTML files, images, videos and Adobe Acrobat (PDF) documents.

Alternatively, if the request is for a file that has an extension (such as ASPX) that is mapped to the ASP.NET ISAPI Extension, then the request is handed off to that extension (as indicated by the number 2 in the diagram). At this point, the ASP.NET processing pipeline kicks in. Requests are passed through registered HTTP Modules, and then finally processed by a registered HTTP Handler.

So where does that leave Forms Authentication? The code that implements the functionality that Forms Authentication provides is implemented as a .NET HTTP Module. So, only when a request reaches the position indicated by the number 3 in the diagram, does Forms Authentication functionality kick in. Since requests for static files never make it through to this point, Forms-Based Authentication doesn�t protect those resources from requests.

There are two common ways to have Forms Authentication protect your static resources. The first method involves mapping file extensions for static files to the ASP.NET ISAPI Extension. After this is done, requests for those static resources will be handled by ASP.NET rather than by the Static File Handler. This allows the Forms Authentication HTTP Module to protect access to those resources. It should be noted that implementing this mechanism does impose some overhead on your system. To implement this:

  1. Open IIS Manager and locate the Web site or Web application root where you static resources are located.

  2. Right-click and choose "Properties."

  3. On the "Home Directory" (for a Web site) or "Directory" (for a Web application) tab click the "Configuration" button.

  4. On the "Mappings" tab locate an entry (such as ASPX) that is mapped to the ASP.NET ISAPI Extension. Select it and click the "Edit" button. In the "executable" text box, select all the text and copy it to the Windows clipboard (by right-clicking and choosing "Copy"). Click "OK" to close the dialogue, and return to the "Mappings" tab.

  5. Now click the "Add" button to add a new mapping. Paste the executable path (by right-clicking and choosing "Paste") into the executable text box. Add the file extension of the files you wish to protect into the Extension text box. Set the allowed verbs to "GET,HEAD,POST,DEBUG" and any additional HTTP verbs you wish to access. Ensure that "Script engine" box is checked.

    If your browser does not support inline frames, click here to view on a separate page.

  6. Click "OK" to add the new script mapping. Now documents with the file extension you entered will be processed by the .NET runtime, and can be protected with ASP.NET Forms Authentication.

The second method commonly used involves moving all the static content you wish to protect outside your Web site. In your Web site you�ll create a page that validates that the user is allowed to download the document. If the user is allowed to download the document, the ASP.NET page will read the file off the hard disk, and stream it to the user after setting appropriate HTTP headers. Because this solution involves writing some custom code to implement the authentication and authorization sections, it�s beyond the scope of this article. However a number of tutorials exist on popular ASP.NET Web sites.

It�s interesting to note that the problem of "two pipelines" is resolved in IIS 7, which fully integrates IIS and ASP.NET -- one result of which is a single, unified event pipeline. For more information on IIS 7, see: http://www.microsoft.com/technet/prodtechnol/windowsserver2003/library/

For More Information

Submit your questions to the IIS Insider. A response is not guaranteed; however, selected questions along with the answers will be posted in a future IIS Insider column.

For a list of previous months' questions and answers on IIS Insider columns, click here.

We at Microsoft Corporation hope that the information in this work is valuable to you. Your use of the information contained in this work, however, is at your sole risk. All information in this work is provided "as is," without any warranty, whether express or implied, of its accuracy, completeness, fitness for a particular purpose, title or non-infringement, and none of the third-party products or information mentioned in the work are authored, recommended, supported or guaranteed by Microsoft Corporation. Microsoft Corporation shall not be liable for any damages you may sustain by using this information, whether direct, indirect, special, incidental or consequential, even if it has been advised of the possibility of such damages.