Impersonation
Impersonation is the capability for the ASP.NET process to run in the context of a particular user identity. It is said to "impersonate" the logged-in user and is capable of using the logged-in user's identity to act on the user's behalf.By default, Impersonation is not enabled in ASP.NET. You might initially doubt this because if you look at the User.Identity.Name property with Windows authentication enabled, it will be set to the logged-in user. This, however, is not the identity that the ASP.NET application is using to access resources. The identity that is shown here is used during URL authorization and file authorization, but will not be used as the identity when calling other base class functionality.
Determining Identity with WindowsIdentity
To determine the identity under which the ASP.NET process is running, you can use a static method, GetCurrent, of the WindowsIdentity to return the identity under which the current process is executing. When you examine the name returned by GetCurrent, you will see that you are really running under the SYSTEM account.Listings 7.20 and 7.21 show a page that compares the results from User.Identity and WindowsIdentity.GetCurrent().
Listing 7.20 Webform1.aspx
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false"
Inherits="DefaultImpersonation.WebForm1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<meta name="GENERATOR" Content="Microsoft Visual Studio 7.0">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name="vs_defaultClientScript" content="JavaScript (ECMAScript)">
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/
intellisense/ie5">
</HEAD>
<body>
<form id="Form1" method="post" runat="server">
<P>
<STRONG style="FONT-FAMILY: Verdana">Windows Impersonation</STRONG>
</P>
<TABLE style="FONT-FAMILY: Verdana" cellSpacing="1" cellPadding="1"
width="300" border="1">
<TR>
<TD colspan="2">
<STRONG>User</STRONG>
</TD>
</TR>
<TR>
<TD>
IsAuthenticated:
</TD>
<TD>
<asp:Label id="lblUserIsAuthenticated"
runat="server"></asp:Label>
</TD>
</TR>
<TR>
<TD>
Authentication Type:
</TD>
<TD>
<asp:Label id="lblUserAuthenticationType"
runat="server"></asp:Label>
</TD>
</TR>
<TR>
<TD>
Name:
</TD>
<TD>
<asp:Label id="lblUserName" runat="server"></asp:Label>
</TD>
</TR>
<TR>
<TD>
</TD>
<TD>
</TD>
</TR>
<TR>
<TD colspan="2">
<STRONG>WindowsIdentity</STRONG>
</TD>
</TR>
<TR>
<TD>
IsAuthenticated
</TD>
<TD>
<asp:Label id="lblWIIsAuthenticated"
runat="server"></asp:Label>
</TD>
</TR>
<TR>
<TD>
AuthenticationType
</TD>
<TD>
<asp:Label id="lblWIAuthenticationType"
runat="server"></asp:Label>
</TD>
</TR>
<TR>
<TD>
Name:
</TD>
<TD>
<asp:Label id="lblWIName" runat="server"></asp:Label>
</TD>
</TR>
<TR>
<TD>
</TD>
<TD>
</TD>
</TR>
</TABLE>
</form>
</body>
</HTML>
Listing 7.21 The Code Behind Class for WebForm1.aspx Showing the Difference Between User.Identity and WindowsIdentity.GetCurrent() with Impersonation Disabled
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace DefaultImpersonation
{
/// <summary>
/// Summary description for WebForm1.
/// </summary>
public class WebForm1 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Label lblUserIsAuthenticated;
protected System.Web.UI.WebControls.Label lblUserAuthenticationType;
protected System.Web.UI.WebControls.Label lblUserName;
protected System.Web.UI.WebControls.Label lblWIIsAuthenticated;
protected System.Web.UI.WebControls.Label lblWIAuthenticationType;
protected System.Web.UI.WebControls.Label lblWIName;
public WebForm1()
{
Page.Init += new System.EventHandler(Page_Init);
}
private void Page_Load(object sender, System.EventArgs e)
{
this.lblUserIsAuthenticated.Text =
User.Identity.IsAuthenticated.ToString();
this.lblUserAuthenticationType.Text = User.Identity.
AuthenticationType.ToString();
this.lblUserName.Text = User.Identity.Name;
System.Security.Principal.WindowsIdentity wi = System.Security.
Principal.WindowsIdentity.GetCurrent();
this.lblWIAuthenticationType.Text = wi.AuthenticationType.ToString();
this.lblWIIsAuthenticated.Text = wi.IsAuthenticated.ToString();
this.lblWIName.Text = wi.Name;
}
private void Page_Init(object sender, EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
}
#region Web Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
}
}
Running this page returns the following:
User | |
---|---|
IsAuthenticated: | True |
Authentication Type: | NTLM |
Name: | KINSMAN\ckinsman |
WindowsIdentity | |
IsAuthenticated: | True |
AuthenticationType: | NTLM |
Name: | NT AUTHORITY\SYSTEM |
Listing 7.22 Web.config Set Up for Impersonation
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<identity impersonate="true" />
<compilation defaultLanguage="c#" debug="true" />
<authentication mode="Windows" />
<authorization>
<allow users="*" /> <!-- Allow all users -->
</authorization>
</system.web>
</configuration>
If you run the same page shown in Listing 7.21, you will find that the names returned by WindowsIdentity.GetCurrent and by User.Identity are the same. The output from the page will look like this:
User | |
---|---|
IsAuthenticated: | True |
Authentication Type: | NTLM |
Name: | KINSMAN\ckinsman |
WindowsIdentity | |
IsAuthenticated: | True |
AuthenticationType: | NTLM |
Name: | KINSMAN\ckinsman |
User | |
---|---|
IsAuthenticated: | False |
Authentication Type: | |
Name: | |
WindowsIdentity | |
IsAuthenticated: | True |
AuthenticationType: | NTLM |
Name: | KINSMAN\IUSR_STEPTOE |
Hard-Coded Impersonation
ASP.NET provides an additional option for impersonation. It is possible within the <identity> element to hard-code the account that you would like ASP.NET to run under. If you hard-code the account into the identity element, this account is used to run the ASP.NET process regardless of whether the user is authenticated or not. Let's take a look at this. Listing 7.23 shows the modified web.config with a hard-coded user account.
Listing 7.23 Web.config with a Hard-Coded Impersonation Account
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<identity impersonate="true" userName="KINSMAN\ChrisKinsman"
password="password" />
<compilation defaultLanguage="c#" debug="true" />
<authentication mode="Windows" />
<authorization>
<allow users="*" /> <!-- Allow all users -->
</authorization>
</system.web>
</configuration>
If you modify the web.config as shown in Listing 7.23 and run the same page with anonymous enabled, you will get the following output:
User | |
---|---|
IsAuthenticated: | False |
Authentication Type: | |
Name: | |
WindowsIdentity | |
IsAuthenticated: | True |
AuthenticationType: | NTLM |
Name: | KINSMAN\ChrisKinsman |
User | |
---|---|
IsAuthenticated: | True |
Authentication Type: | NTLM |
Name: | KINSMAN\ckinsman |
WindowsIdentity | |
IsAuthenticated: | True |
AuthenticationType: | NTLM |
Name: | KINSMAN\ChrisKinsman |