ASP.NET Impersonation
When using impersonation, ASP.NET applications can optionally execute with the identity of the client on whose behalf they are operating. The usual reason for doing this is to avoid dealing with authentication and authorization issues in the ASP.NET application code. Instead, you rely on Microsoft Internet Information Services (IIS) to authenticate the user and either pass an authenticated token to the ASP.NET application or, if unable to authenticate the user, pass an unauthenticated token. In either case, the ASP.NET application impersonates whichever token is received if impersonation is enabled. The ASP.NET application, now impersonating the client, then relies on the settings in the NTFS directories and files to allow it to gain access, or not. Be sure to format the server file space as NTFS, so that access permissions can be set.
Impersonation is disabled by default. For ASP compatibility, the user must explicitly enable impersonation. If impersonation is enabled for a given application, ASP.NET always impersonates the access token that IIS provides to ISAPI extensions. That token can be either an authenticated user token, or the token for the anonymous user (such as IUSR_MACHINENAME). The impersonation occurs regardless of the type of authentication being used in the application.
Only application code is impersonated; compilation and configuration are read as the process token. The result of the compilation is put in the "Temporary ASP.NET files" directory. The account that is being impersonated needs to have read/write access to this directory. If an application is on a universal naming convention (UNC) share, ASP.NET will always impersonate the token provided to IIS to access that share unless a configured account is used. If an explicit configured account is provided, ASP.NET will use that account in preference to the IIS UNC token. Applications that do want per-request impersonation can simply be configured to impersonate the user making the request.
Impersonation is disabled at the computer level by default and, unless overridden, all the application domains inherit this setting. You can enable impersonation by putting a configuration file in the application root directory. For more information about the ASP.NET configuration system, see ASP.NET Configuration.
As is the case with other configuration directives, this directive applies hierarchically. It is respected by nested applications in the hierarchy, unless explicitly overridden. The default value for this setting is as follows.
<impersonation enable="false"/>
A minimal configuration file to enable impersonation for an application might look similar to the following example.
<!-- Web.config file. -->
<identity impersonate="true"/>
There is also name support for running an application as a configurable identity. For example:
<identity impersonate="true" userName="contoso\Jane" password="pass"/>
This enables the entire application to run as contoso\Jane
, regardless of the identity of the request, as long as the password is correct. This type of impersonation can be delegated to another computer.
You can programmatically read the identity of the impersonated user, as shown in the following example.
Dim username As String = System.Security.Principal.WindowsIdentity.GetCurrent().Name
[C#]
String username = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
In the preceding example, userName and password are stored in clear text in the configuration file. Although IIS will not transmit .config files in response to a user agent request, configuration files can be read by other means, for instance by an authenticated user with proper credentials on the domain that contains the server. To help increase security, the identity section supports storage of encrypted userName and password attributes in the registry as shown in the following example.
userName="registry:HKLM\Software\AspNetIdentity,Name"
password="registry:HKLM\Software\AspNetIdentity,Password"
The portion of the string after the keyword registry and before the comma indicates the name of the registry key that ASP.NET opens. The portion after the comma contains a single string value name from which ASP.NET will read the credentials. The comma is required, and the credentials must be stored in the HKLM hive. If the configuration format is incorrect, ASP.NET will not launch the worker process and the current account creation failure code path will be followed.
The credentials must be in REG_BINARY format, containing the output of a call to the Windows API function CryptProtectData. You can create the encrypted credentials and store them in the registry with the ASP.NET Set Registry console application(Aspnet_setreg.exe), which uses CryptProtectData to accomplish the encryption. To download Aspnet_setreg.exe, along with the Visual C++ source code and documentation, visit the Web site www.asp.net and search for "aspnet_setreg".
You should configure access to the key storing the encrypted credentials so that access is provided only to Administrators and SYSTEM. Because the key will be read by the ASP.NET process running as SYSTEM, you should set the following permissions:
Administrators:F
SYSTEM:F
CREATOR OWNER:F
ProcessAccount:R
This provides two lines of defense to protect the data:
- The ACL permissions require the identity accessing the data to be an Administrator.
- An attacker must run code on the server (CryptUnprotectData) to recover the credentials for the account.