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

文章翻譯 文章翻譯
文章編號: 306158 - 檢視此文章適用的產品。
本文參照下列 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.WindowsImpersonationContext
Dim currentWindowsIdentity As System.Security.Principal.WindowsIdentity

currentWindowsIdentity = 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 = 2
Dim LOGON32_PROVIDER_DEFAULT As Integer = 0

Dim impersonationContext As WindowsImpersonationContext

Declare 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 Integer

Declare Auto Function DuplicateToken Lib "advapi32.dll" ( _
                        ByVal ExistingTokenHandle As IntPtr, _
                        ByVal ImpersonationLevel As Integer, _
                        ByRef DuplicateTokenHandle As IntPtr) As Integer

Declare Auto Function RevertToSelf Lib "advapi32.dll" () As Long
Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Long


Public 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 If
End Sub

Private 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 If
End Function

Private 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 知識庫」中的文章:
306590 ASP.NET 安全性概觀 (機器翻譯)
注意 :本文屬於「快速發佈」文章,係由 Microsoft 技術支援或組織內部直接建立。 本文所包含的資訊是為了回應新問題而依現況提供。 因此為了迅速對外發佈,文章內容可能含有印刷錯誤,而且可能會在不另行通知的情況下進行修改。 如需其他考量事項,請參閱使用規定

屬性

文章編號: 306158 - 上次校閱: 2014年4月29日 - 版次: 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
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。

提供意見

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com