http://msdn.microsoft.com/en-us/library/ff647076.aspx
IIS Authentication
When ASP.NET is configured for Windows authentication, it relies on IIS to authenticate its clients using the configured authentication mode. IIS determines the authentication mode for a particular application by examining its metabase settings. After successfully authenticating a user, IIS passes the Windows token representing the authenticated user to the ASP.NET worker process (w3wp.exe) in which the ASP.NET application is hosted. If your application uses a virtual directory that is configured in IIS to support anonymous access, the token represents the anonymous Internet user account; otherwise, the token represents the authenticated user.
IIS supports the following modes of authentication:
- Anonymous. If you do not need to authenticate your clients (or you use a custom authentication mechanism, such as forms authentication), you can configure IIS to allow anonymous access. In this event, IIS creates a Windows token to represent all anonymous users with the same anonymous (or guest) account. The default anonymous account is IUSR_MACHINENAME, where MACHINENAME is the NetBIOS name of the computer that was specified during installation.
- Basic. Basic authentication requires the user to supply credentials in the form of a user name and password to prove their identity. Basic authentication is based on the Internet standard RFC 2617, and is supported by all popular browsers. The user's credentials are transmitted from the browser to the Web server in an unencrypted Base64-encoded format. To help protect the credentials, you should only use basic authentication with Secure Sockets Layer (SSL). Because the Web server obtains the user's credentials unencrypted, ASP.NET applications can impersonate the caller and use their credentials to access network resources.
ASP.NET Authentication
IIS passes to ASP.NET the token that represents the authenticated user or anonymous user account. This token is maintained inside an IIdentity object that is contained inside an IPrincipal object, which, in turn, is attached to the current Web request thread. The IPrincipal and IIdentity objects can be accessed through the HttpContext.User property. These objects and this property are set by authentication modules, which are implemented as HTTP modules and invoked as a standard part of the ASP.NET pipeline, which is shown in Figure 3.
Figure 3. ASP.NET pipeline
The ASP.NET pipeline model consists of an HttpApplication object, various HTTP module objects, and an HTTP handler object, along with their associated factory objects. An HttpRuntime object is used at the start of the processing sequence. Throughout the request life cycle, an HttpContext object is used to convey details about the request and response.
For more information about the ASP.NET request life cycle, see "ASP.NET Life Cycle" at http://msdn.microsoft.com/en-us/library/ms227435(VS.80).aspx.
Authentication Modules
ASP.NET 2.0 defines a set of HTTP modules in the machine-level Web.config file. These include a number of authentication modules as shown here:
<httpModules>
<add name="WindowsAuthentication"
type="System.Web.Security.WindowsAuthenticationModule" />
<add name="FormsAuthentication"
type="System.Web.Security.FormsAuthenticationModule" />
<add name="PassportAuthentication"
type="System.Web.Security.PassportAuthenticationModule" />
</httpModules>
Only one authentication module is loaded, and this is dependent on which authentication mode has been specified in the authentication element of the configuration file. The authentication module creates an IPrincipal object and stores it in the HttpContext.User property. This is vital because other authorization modules use this IPrincipal object to make authorization decisions.
When anonymous access is enabled in IIS and the mode attribute of the authentication element is set to none, there is a special module that puts a default anonymous principal into the HttpContext.User property. As a result, HttpContext.User is never a null reference (Nothing in Visual Basic) after authentication.
WindowsAuthenticationModule
The WindowsAuthenticationModule class is activated when the following element is in the Web.config file.
<authentication mode="Windows" />
The WindowsAuthenticationModule class is responsible for creating WindowsPrincipal and WindowsIdentity objects to represent the authenticated user, and for attaching these objects to the current Web request.
For Windows authentication, the following sequence occurs:
- The WindowsAuthenticationModule class creates a WindowsPrincipal object using the Windows access token that is passed from IIS to ASP.NET. This token is wrapped in the WorkerRequest property of the HttpContext class. When the AuthenticateRequest event is raised, theWindowsAuthenticationModule retrieves the token from the HttpContext class and creates the WindowsPrincipal object. The HttpContext.Userproperty is set with this WindowsPrincipal object and represents the security context of the authenticated user for all authorization modules and ASP.NET pages.
- The WindowsAuthenticationModule class uses P/Invoke to call Win32 functions and obtain the list of Windows groups to which the user belongs. These groups are used to populate the WindowsPrincipal role list.
- The WindowsAuthenticationModule class stores the WindowsPrincipal object in the HttpContext.User property. This is subsequently used by authorization modules to authorize the authenticated user.
Note: The DefaultAuthenticationModule class, which is also part of the ASP.NET pipeline, sets the Thread.CurrentPrincipal property to the same value as the HttpContext.User property. It does so after the AuthenticateRequest event is handled.
Authorization Modules
After the WindowsAuthenticationModule class has finished its processing, the authorization modules are called if the request has not been rejected. The authorization modules are also defined in the httpModules element in the machine-level Web.config file as shown here:
<httpModules>
<add name="UrlAuthorization"
type="System.Web.Security.UrlAuthorizationModule" />
<add name="FileAuthorization"
type="System.Web.Security.FileAuthorizationModule" />
<add name="AnonymousIdentification"
type="System.Web.Security.AnonymousIdentificationModule" />
</httpModules>
UrlAuthorizationModule
When the UrlAuthorizationModule class is called, it checks for an authorization element in either the machine-level or application-specific Web.config file. If present, the UrlAuthorizationModule class retrieves the IPrincipal object from the HttpContext.User property, and then determines whether the user is authorized to access the requested resource by using the specified verb (GET, POST, and so on).
FileAuthorizationModule
Next, the FileAuthorizationModule class is called. It checks whether the IIdentity object in the HttpContext.User.Identity property is an instance of theWindowsIdentity class. If the IIdentity object is not an instance of the WindowsIdentity class, then the FileAuthorizationModule class stops processing.
If an instance of the WindowsIdentity class is present, the FileAuthorizationModule class calls the AccessCheck Win32 function (through P/Invoke) to determine whether the authenticated client is authorized to access the requested file. If the file's security descriptor contains at least a Read Access Control Entry (ACE) in its Discretionary Access Control List (DACL), the request is allowed to proceed. Otherwise, the FileAuthorizationModule class calls theHttpApplication.CompleteRequest method and returns a 401 status code to the client.
Security Context
The .NET Framework encapsulates Windows tokens and logon sessions with the following two interfaces:
- System.Security.Principal.IPrincipal
- System.Security.Principal.IIdentity (This is exposed as a property in the IPrincipal interface.)
HttpContext.User
In ASP.NET, the security context of a user that is authenticated with Windows authentication is represented by the WindowsPrincipal and WindowsIdentityclasses. ASP.NET applications that use Windows authentication can access the WindowsPrincipal class through the HttpContext.User property.
To retrieve the security context of the Windows authenticated user that initiated the current request, use the following code:
using System.Security.Principal; ... // Obtain the authenticated user's Identity WindowsPrincipal winPrincipal = (WindowsPrincipal)HttpContext.Current.User;
WindowsIdentity.GetCurrent
The WindowsIdentity.GetCurrent method can be used to obtain the identity of the security context of the Win32 thread that is currently running. Without impersonation, the thread inherits the security context of the process on IIS 6.0, which is the NetworkService account by default.
This security context is used when accessing local resources. You can override this security context with impersonation by using either the original authenticated user's security context or by using a fixed identity.
To retrieve the security context under which the application is running, use the following code:
using System.Security.Principal; ... // Obtain the authenticated user's identity. WindowsIdentity winId = WindowsIdentity.GetCurrent(); WindowsPrincipal winPrincipal = new WindowsPrincipal(winId);
Thread.CurrentPrincipal
Each thread in an ASP.NET application exposes a CurrentPrincipal object, which holds the original authenticated user's security context. This security context can be used for role-based authorization.
To retrieve the thread's current principal, use following code:
using System.Security.Principal; ... // Obtain the authenticated user's identity WindowsPrincipal winPrincipal = (WindowsPrincipal) Thread.CurrentPrincipal();
Table 1 shows the resulting identities that are obtained from the various identity properties available to ASP.NET application code when your application uses Windows authentication and IIS is configured to use Integrated Windows authentication.
Table 1: Thread Exposed CurrentPrincipal Object
Web.config settings | Variable location | Resultant identity |
---|---|---|
<identity impersonate="true"/> <authentication mode="Windows" /> | HttpContext WindowsIdentity Thread | Domain\UserName Domain\UserName Domain\UserName |
<identity impersonate="false"/> <authentication mode="Windows" /> | HttpContext WindowsIdentity Thread | Domain\UserName NT AUTHORITY\NETWORK SERVICE Domain\UserName |
<identity impersonate="true"/> <authentication mode="Forms" /> | HttpContext WindowsIdentity Thread | Name provided by user Domain\UserName Name provided by user |
<identity impersonate="false"/> <authentication mode="Forms" /> | HttpContext WindowsIdentity Thread | Name provided by user NT AUTHORITY\NETWORK SERVICE Name provided by user |
Impersonation
An ASP.NET application can use impersonation to perform operations and access resources with the security context of the authenticated client or of a specific Windows account.
Original User Impersonation
To impersonate the original (authenticated) user, use the following configuration in the Web.config file:
<authentication mode="Windows" /> <identity impersonate="true" />
With this configuration, ASP.NET always impersonates the authenticated user, and all resource access is performed using the authenticated user's security context. If anonymous access is enabled on your application's virtual directory, the IUSR_MACHINENAME account is impersonated.
To temporarily impersonate the authenticated caller, set the impersonate attribute of the identity element to false, and then use the following code:
using System.Security.Principal; ... // Obtain the authenticated user's identity. WindowsIdentity winId = (WindowsIdentity)HttpContext.Current.User.Identity; WindowsImpersonationContext ctx = null; try { // Start impersonating. ctx = winId.Impersonate(); // Now impersonating. // Access resources using the identity of the authenticated user. } // Prevent exceptions from propagating. catch { } finally { // Revert impersonation. if (ctx != null) ctx.Undo(); } // Back to running under the default ASP.NET process identity.
This code impersonates the original authenticated user. The original user's identity and Windows token are maintained in theHttpContext.Current.User.Identity object.
Fixed Identity Impersonation
If you need to impersonate the same identity throughout the lifetime of your application, you can specify credentials on the identity element in your Web.config file. The following example shows how to impersonate a Windows account named "TestUser".
<identity impersonate="true" username="TestUser" password="P@ssw0rd" />
If you use this approach, you should encrypt the credentials. With ASP.NET 2.0, you can use the ASP.NET IIS Registration Tool (Aspnet_regiis.exe). With ASP.NET version 1.1, you can use the Aspnet_setreg.exe utility. For more information about this utility, see http://msdn.microsoft.com/en-us/library/k6h9cz8h(VS.71).aspx.
To use a fixed identity for resource access in ASP.NET applications, you can configure credentials by using the identity element on Windows 2000 Server or Windows Server 2003. If you are running Windows Server 2003 with IIS 6.0 configured to run in worker process isolation mode (the default), you can avoid impersonation by configuring your ASP.NET application to run in a custom application pool that runs under a specific domain identity. Then you can use the specified domain identity to access resources without using impersonation.
Delegation
Impersonation gives access to local resources only. Delegation is an extended impersonation capability that enables you to use an impersonation token to access network resources.
If your application uses Kerberos v5 authentication to authenticate its users, you can use Kerberos delegation to pass the user's identity through the layers of your application and to access network resources. If your application does not use Kerberos v5 authentication, you can use protocol transition to switch to Kerberos, and then use delegation to pass on the identity.
Constrained delegation in Windows Server 2003 requires Kerberos authentication. If your application cannot use Kerberos authentication to authenticate its callers, you can use protocol transition to switch from an alternate, non-Windows authentication mode (such as forms or certificate authentication) to Kerberos authentication. You can then use Kerberos with constrained delegation to access downstream network resources.
Constrained and Unconstrained Delegation
Kerberos delegation on Windows 2000 Server is unconstrained. Servers that are configured for delegation in Active Directory can access any network resources or any computer on the network while using the impersonated user's security context. This represents a potential security threat, particularly if the Web server is compromised by a malicious user.
To address this security issue, Windows Server 2003 introduces constrained delegation. This enables administrators to specify exactly which services another server or domain account can access when using an impersonated user's security context.
Configuring Delegation
To use Kerberos delegation, appropriate Active Directory configuration is required.
To grant the Web server the right to delegate client credentials, configure Active Directory as follows:
- If you run your application under the NetworkService account, the Web server computer account must be marked in Active Directory as trusted for delegation.
- If you run your application under a custom domain account, this user account must be marked in Active Directory as trusted for delegation.
- If your application impersonates a user account, make sure that the user account your application impersonates is not marked as "Sensitive and cannot be delegated" in Active Directory.
For more information about protocol transition and constrained delegation, see How To: Use Protocol Transition and Constrained Delegation in ASP.NET 2.0.