您目前已離線,請等候您的網際網路重新連線

如何在 ASP.NET 應用程式中實作模擬

本文參照下列 Microsoft .NET Framework Class Library 命名空間:
  • System.Web.Security
  • System.Security.Principal
  • System.Runtime.InteropServices
結論
本文說明在 ASP.NET 應用程式中實作模擬的不同方式。
其他相關資訊
如果您想要在 ASP.NET 的執行緒上模擬使用者,可以視需求而使用下列任一種方法:
注意 您可以使用下列程式碼決定執行執行緒的使用者身分:
System.Security.Principal.WindowsIdentity.GetCurrent().Name				

模擬 IIS 驗證帳戶或使用者

為模擬 Microsoft Internet Information Services (IIS) 在 ASP. NET 應用程式中,針對每一頁和每一個要求驗證使用者,您必須將 <身分識別> 標記在此應用程式的 Web.config 檔案中,並將模擬屬性設定為。例如:
<identity impersonate="true" />				
回到頁首

模擬在 ASP.NET 應用程式中單一特定使用者的所有要求

若要模擬 ASP.NET 應用程式中單一特定使用者在所有頁面的所有要求,您可以在此應用程式專屬 Web.config 檔案的 <身分識別> 標籤中,指定 userNamepassword 屬性。例如:
<identity impersonate="true" userName="accountname" password="password" />				
注意 在執行緒上模擬特定使用者的處理程序身分識別必須具有「作為作業系統一部分」的權限。依預設,Aspnet_wp.exe 程序是在名為 ASPNET 的電腦帳戶下執行。不過,這個帳戶沒有模擬特定使用者需要的權限。嘗試模擬特定使用者時收到錯誤訊息。此資訊僅適用於.NET Framework 1.0。.NET Framework 1.1 不需要此權限。

如果要解決這個問題,請使用下列其中一個方法:
  • 將「作為作業系統一部分」的權限授予 ASPNET 帳戶 (最小權限的帳戶)。

    注意 雖然可以使用此方法解決問題,但 Microsoft 不建議使用。
  • 在 Machine.config 檔案的 <processModel> 組態區段中,變更在系統帳戶下執行的 Aspnet_wp.exe 程序帳戶。
回到頁首

模擬在程式碼中進行驗證的使用者

僅在執行特定程式碼區段時模擬驗證使用者 (User.Identity),才能使用下列程式碼。此方法要求進行驗證的使用者身分應屬於 WindowsIdentity 類型。

Visual Basic .NET
Dim impersonationContext As System.Security.Principal.WindowsImpersonationContextDim currentWindowsIdentity As System.Security.Principal.WindowsIdentitycurrentWindowsIdentity = CType(User.Identity, System.Security.Principal.WindowsIdentity)impersonationContext = currentWindowsIdentity.Impersonate()'Insert your code that runs under the security context of the authenticating user here.impersonationContext.Undo()				
Visual C# .NET
System.Security.Principal.WindowsImpersonationContext impersonationContext;impersonationContext =     ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();//Insert your code that runs under the security context of the authenticating user here.impersonationContext.Undo();				
Visual J# .NET
System.Security.Principal.WindowsImpersonationContext impersonationContext;impersonationContext =     ((System.Security.Principal.WindowsIdentity)get_User().get_Identity()).Impersonate();//Insert your code that runs under the security context of the authenticating user here.impersonationContext.Undo();				
回到頁首

模擬程式碼中的特定使用者

當您執行程式碼特定區段,欲模擬特定使用者,可使用下列程式碼:

Visual Basic .NET
<%@ Page Language="VB" %><%@ Import Namespace = "System.Web" %><%@ Import Namespace = "System.Web.Security" %><%@ Import Namespace = "System.Security.Principal" %><%@ Import Namespace = "System.Runtime.InteropServices" %><script runat=server>Dim LOGON32_LOGON_INTERACTIVE As Integer = 2Dim LOGON32_PROVIDER_DEFAULT As Integer = 0Dim impersonationContext As WindowsImpersonationContextDeclare Function LogonUserA Lib "advapi32.dll" (ByVal lpszUsername As String, _                        ByVal lpszDomain As String, _                        ByVal lpszPassword As String, _                        ByVal dwLogonType As Integer, _                        ByVal dwLogonProvider As Integer, _                        ByRef phToken As IntPtr) As IntegerDeclare Auto Function DuplicateToken Lib "advapi32.dll" ( _                        ByVal ExistingTokenHandle As IntPtr, _                        ByVal ImpersonationLevel As Integer, _                        ByRef DuplicateTokenHandle As IntPtr) As IntegerDeclare Auto Function RevertToSelf Lib "advapi32.dll" () As LongDeclare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As LongPublic Sub Page_Load(ByVal s As Object, ByVal e As EventArgs)    If impersonateValidUser("username", "domain", "password") Then        'Insert your code that runs under the security context of a specific user here.        undoImpersonation()    Else        'Your impersonation failed. Therefore, include a fail-safe mechanism here.    End IfEnd SubPrivate Function impersonateValidUser(ByVal userName As String, _ByVal domain As String, ByVal password As String) As Boolean    Dim tempWindowsIdentity As WindowsIdentity    Dim token As IntPtr = IntPtr.Zero    Dim tokenDuplicate As IntPtr = IntPtr.Zero    impersonateValidUser = False    If RevertToSelf() Then        If LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,                      LOGON32_PROVIDER_DEFAULT, token) <> 0 Then            If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then                tempWindowsIdentity = New WindowsIdentity(tokenDuplicate)                impersonationContext = tempWindowsIdentity.Impersonate()                If Not impersonationContext Is Nothing Then                    impersonateValidUser = True                End If            End If        End If    End If    If Not tokenDuplicate.Equals(IntPtr.Zero) Then        CloseHandle(tokenDuplicate)    End If    If Not token.Equals(IntPtr.Zero) Then        CloseHandle(token)    End IfEnd FunctionPrivate Sub undoImpersonation()    impersonationContext.Undo()End Sub</script>
Visual C# .NET
<%@ Page Language="C#"%><%@ Import Namespace = "System.Web" %><%@ Import Namespace = "System.Web.Security" %><%@ Import Namespace = "System.Security.Principal" %><%@ Import Namespace = "System.Runtime.InteropServices" %><script runat=server>public const int LOGON32_LOGON_INTERACTIVE = 2;public const int LOGON32_PROVIDER_DEFAULT = 0;WindowsImpersonationContext impersonationContext; [DllImport("advapi32.dll")]public static extern int LogonUserA(String lpszUserName, 	String lpszDomain,	String lpszPassword,	int dwLogonType, 	int dwLogonProvider,	ref IntPtr phToken);[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]public static extern int DuplicateToken(IntPtr hToken, 	int impersonationLevel,  	ref IntPtr hNewToken);                          [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]public static extern bool RevertToSelf();[DllImport("kernel32.dll", CharSet=CharSet.Auto)]public static extern  bool CloseHandle(IntPtr handle);public void Page_Load(Object s, EventArgs e){	if(impersonateValidUser("username", "domain", "password"))	{		//Insert your code that runs under the security context of a specific user here.		undoImpersonation();	}	else	{		//Your impersonation failed. Therefore, include a fail-safe mechanism here.	}}private bool impersonateValidUser(String userName, String domain, String password){	WindowsIdentity tempWindowsIdentity;	IntPtr token = IntPtr.Zero;	IntPtr tokenDuplicate = IntPtr.Zero;	if(RevertToSelf())	{		if(LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, 			LOGON32_PROVIDER_DEFAULT, ref token) != 0)		{			if(DuplicateToken(token, 2, ref tokenDuplicate) != 0) 			{				tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);				impersonationContext = tempWindowsIdentity.Impersonate();				if (impersonationContext != null)				{					CloseHandle(token);					CloseHandle(tokenDuplicate);					return true;				}			}		} 	}	if(token!= IntPtr.Zero)		CloseHandle(token);	if(tokenDuplicate!=IntPtr.Zero)		CloseHandle(tokenDuplicate);	return false;}private void undoImpersonation(){	impersonationContext.Undo();}</script>
Visual J# .NET
<%@ Page language="VJ#" %><%@ Import Namespace="System.Web" %><%@ Import Namespace="System.Web.Security" %><%@ Import Namespace="System.Security.Principal" %><%@ Import Namespace="System.Runtime.InteropServices" %><script runat=server>public static int LOGON32_LOGON_INTERACTIVE = 2;public static int LOGON32_PROVIDER_DEFAULT = 0;WindowsImpersonationContext impersonationContext; /** @attribute DllImport("advapi32.dll") */ public static native int LogonUserA(String lpszUserName, 	String lpszDomain, 	String lpszPassword,	int dwLogonType, 	int dwLogonProvider, 	System.IntPtr[] phToken);/** @attribute DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true) */ public static native int DuplicateToken(System.IntPtr hToken,	int impersonationLevel,	System.IntPtr[] hNewToken);/** @attribute DllImport("kernel32.dll",CharSet=CharSet.Auto) */ public static native  boolean CloseHandle(System.IntPtr[] handle);/** @attribute DllImport("advapi32.dll", 	 CharSet=CharSet.Auto,SetLastError=true) */	 public static native boolean RevertToSelf();public void Page_Load(Object s, System.EventArgs e){	if(impersonateValidUser("username", "domain", " password"))	{		//Insert your code that runs under the security context of a specific user here.		undoImpersonation();	}	else	{		//Your impersonation failed. Therefore, include a fail-safe mechanism here.	}}private boolean impersonateValidUser(String userName, String domain, String password){	WindowsIdentity tempWindowsIdentity;	System.IntPtr[] token = new System.IntPtr[1];	System.IntPtr[] tokenDuplicate = new System.IntPtr[1];	if(RevertToSelf())	{		if(LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, 			LOGON32_PROVIDER_DEFAULT, token) != 0)		{			if(DuplicateToken(token[0], 2, tokenDuplicate) != 0) 			{				tempWindowsIdentity = new WindowsIdentity(tokenDuplicate[0]);				impersonationContext = tempWindowsIdentity.Impersonate();				if (impersonationContext != null)				{					CloseHandle(tokenDuplicate);					CloseHandle(token);					return true;				}							}					} 	}	if(!token[0].Equals(System.IntPtr.Zero))		CloseHandle(token);	if(!tokenDuplicate[0].Equals(System.IntPtr.Zero))		CloseHandle(tokenDuplicate);	return false;}private void undoImpersonation(){	impersonationContext.Undo();}</script>				
注意 如果 Aspnet_wp.exe 程序執行於 Microsoft Windows 2000 電腦中,則模擬執行緒上特定使用者的程序身分必須具有「作為作業系統一部分」的權限。如果在使用 Windows XP 或 Windows Server 2003 電腦中執行 Aspnet_wp.exe 程序,則不需要「作為作業系統一部分」權限。依預設,Aspnet_wp.exe 程序是在名為 ASPNET 的電腦帳戶下執行。不過,這個帳戶沒有模擬特定使用者需要的權限。嘗試模擬特定使用者時收到錯誤訊息。 .

如果要解決這個問題,請使用下列其中一個方法:
  • 將「作為作業系統一部分」的權限授予 ASPNET 帳戶。

    注意 不建議使用此方法解決問題。
  • 在 Machine.config 檔案的 <processModel> 組態區段中,變更在系統帳戶下執行的 Aspnet_wp.exe 程序帳戶。
回到頁首
参考
如需有關 ASP.NET 安全性的詳細資訊,請按一下下面的文章編號,檢視「Microsoft 知識庫」中的文章:
306590ASP.NET 安全性概觀 (機器翻譯)
login failed null (null) impersonate
注意 :本文屬於「快速發佈」文章,係由 Microsoft 技術支援或組織內部直接建立。 本文所包含的資訊是為了回應新問題而依現況提供。 因此為了迅速對外發佈,文章內容可能含有印刷錯誤,而且可能會在不另行通知的情況下進行修改。 如需其他考量事項,請參閱使用規定
內容

文章識別碼:306158 - 最後檢閱時間:04/29/2014 10:21:00 - 修訂: 1.0

Microsoft ASP.NET 1.0, Microsoft ASP.NET 1.1, Microsoft Visual Basic .NET 2002 Standard Edition, Microsoft Visual Basic .NET 2003 Standard Edition, Microsoft Visual C# .NET 2002 Standard Edition, Microsoft Visual C# .NET 2003 標準版, Microsoft Visual J# .NET 2003 Standard Edition

  • kbinfo kbsecurity KB306158
意見反應