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

文章翻譯 文章翻譯
文章編號: 306158 - 檢視此文章適用的產品。
本文曾發行於 CHT306158
本文參照下列 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 驗證的帳戶或使用者

如果要在 ASP.NET 應用程式中的每個網頁,在每次收到要求時模擬 Microsoft Internet Information Services (IIS) 進行驗證的使用者,您就必須在這個應用程式的 Web.config 檔案中,加入 <identity> 標籤,並將 impersonate 屬性設為 true。例如:
<identity impersonate="true" />
				

在所有 ASP.NET 應用程式要求時模擬特定使用者

如果要在 ASP.NET 應用程式中的每個網頁,在每次收到要求時模擬特定使用者,您可以在 Web.config 檔案的 <identity> 標籤中,指定該應用程式的 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 處理程序的帳戶變更成 System 帳戶。

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

如果您只要在執行特定程式碼區段時才模擬進行驗證的使用者 (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 處理程序會在名為 ASPNET 的電腦帳戶下執行。但是,這個帳戶並沒有可模擬特定使用者的必要權限。所以,您會在嘗試模擬特定使用者時,收到錯誤訊息。 這項資訊僅適用於 .NET Framework 1.0。.NET Framework 1.1 並不會要求這個權限。

如果需要替代的解決方案,請使用下列其中一種方法:
  • 將「作為作業系統的一部份」權限授予 ASPNET 帳戶。

    注意 我們不建議您採用此方法來暫時解決這個問題。
  • 在 Machine.config 檔案的 <processModel> 組態區段中,將其下執行有 Aspnet_wp.exe 處理程序的帳戶變更成 System 帳戶。

?考

如需有關 ASP.NET 安全性的詳細資訊,請按一下下面的文件編號,檢視「Microsoft 知識庫」中的文件:
306590 INFO:ASP.NET 安全性概觀

屬性

文章編號: 306158 - 上次校閱: 2005年7月11日 - 版次: 4.6
這篇文章中的資訊適用於:
  • 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