摘要預設情況下,ASP.NET應用程式以原生ASPNET帳號運行,該帳號屬於普通使用者組,許可權受到一定的限制,以保障ASP.NET應用程式啟動並執行安全。但是有時需要某個ASP.NET應用程式或者程式中的某段代碼執行需要特定許可權的操作,比如某個檔案的存取,這時就需要給該程式或相應的某段代碼賦予某個帳號的許可權以執行該操作,這種方法稱之為身份類比(Impersonation)。本文介紹了在ASP.NET應用程式中使用身份類比的幾種方法,並比較了它們各自適用的範圍。在閱讀本文之前,建議您先閱讀文章:《ASP .NET 中的身分識別驗證:.NET 安全性指導》 以便對ASP.NET的安全控制有一個總體的瞭解。目錄
- ASP.NET中的身份類比
- 類比IIS認證帳號
- 在某個ASP.NET應用程式中類比指定的使用者帳號
- 在代碼中類比IIS認證帳號
- 在代碼中類比指定的使用者帳號
- 更多資訊
ASP.NET中的身份類比ASP.NET 通過使用身分識別驗證提供者來實現身分識別驗證,一般情況下,ASP.NET的身分識別驗證提供者包括表單身分識別驗證、Windows身分識別驗證和Passport身分識別驗證3種。當通過身分識別驗證後,ASP.NET會檢查是否啟用身份類比。如果啟用,ASP .NET 應用程式使用用戶端標識以用戶端的身份有選擇地執行。否則,ASP.NET應用程式使用本機身份標識運行(一般使用原生ASPNET帳號),具體流程如所示:
在ASP.NET應用程式中使用身份類比一般用於資源存取控制,主要有如下幾種方法:
- 類比IIS認證帳號
- 在某個ASP.NET應用程式中類比指定的使用者帳號
- 在代碼中類比IIS認證帳號
- 在代碼中類比指定的使用者帳號
類比IIS認證帳號這是最簡單的一種方法,使用經過IIS認證的帳號執行應用程式。您需要在Web.config檔案中添加<identity>標記,並將impersonate屬性設定為true:
<identity impersonate="true" />
在這種情況下,使用者身份的認證交給IIS來進行。當允許匿名登入時,IIS將一個匿名登入使用的標識(預設情況下是IUSR_MACHINENAME)交給ASP.NET應用程式。當不允許匿名登入時,IIS將認證過的身份標識傳遞給ASP.NET應用程式。ASP.NET的具體存取權限由該帳號的許可權決定。類比指定的使用者帳號當ASP.NET應用程式需要以某個特定的使用者帳號執行,可以在Web.config檔案的<identity>標記中指定具體的使用者帳號:
<identity impersonate="true" userName="accountname" password="password" />
這時該ASP.NET應用程式的所有頁面的所有請求都將以指定的使用者帳號許可權執行。在代碼中類比IIS認證帳號在代碼中使用身份類比更加靈活,可以在指定的程式碼片段中使用身份類比,在該程式碼片段之外恢複使用ASPNET本機帳號。該方法要求必須使用Windows的認證身份標識。下面的例子在代碼中類比IIS認證帳號: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 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 Auto Function LogonUser 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, _ImpersonationLevel As Integer, _ByRef DuplicateTokenHandle As IntPtr) As IntegerPublic Sub Page_Load(s As Object, 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(userName As String, _domain As String, password As String) As BooleanDim tempWindowsIdentity As WindowsIdentityDim token As IntPtrDim tokenDuplicate As IntPtrIf LogonUser(userName, domain, password, LOGON32_LOGON_INTERACTIVE, _LOGON32_PROVIDER_DEFAULT, token) <> 0 ThenIf DuplicateToken(token, 2, tokenDuplicate) <> 0 ThentempWindowsIdentity = new WindowsIdentity(tokenDuplicate)impersonationContext = tempWindowsIdentity.Impersonate()If impersonationContext Is Nothing ThenimpersonateValidUser = FalseElseimpersonateValidUser = TrueEnd IfElseimpersonateValidUser = FalseEnd IfElseimpersonateValidUser = FalseEnd 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", CharSet=CharSet.Auto)]public static extern int LogonUser(String lpszUserName,String lpszDomain,String lpszPassword,int dwLogonType,int dwLogonProvider,ref IntPtr phToken);[DllImport("advapi32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto, SetLastError=true)]public extern static int DuplicateToken(IntPtr hToken,int impersonationLevel,ref IntPtr hNewToken);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(LogonUser(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)return true;elsereturn false;}elsereturn false;}elsereturn false;}private void undoImpersonation(){impersonationContext.Undo();}</script>下面介紹ASP.NET應用程式中使用身份類比的一個簡單應用。例如有一個ASP.NET應用程式要檢查伺服器端某個檔案是否存在,相應的程式碼為:
bool a = File.Exists("D:\\Share\\test.txt");預設情況下該ASP.NET應用程式以ASPNET帳號運行。為了安全起見,ASPNET這個帳號並沒有伺服器端D:\Share\這個目錄的存取權限。在不使用身份類比的情況下,由於ASP.NET應用程式不具有訪問該目錄的許可權,無論檔案是否存在,File.Exists的傳回值將永遠是false。為瞭解決這個問題,可以另建一個使用者帳號:FileExist,並賦予該帳號D:\Share\目錄的存取權限。然後在該應用程式的Web.config檔案的<identity>標記中指定具體的使用者帳號:
<identity impersonate="true" userName="FileExist" password="password" />
來執行該程式。更多資訊請訪問以下連結擷取更多資訊:1. INFO: Implementing Impersonation in an ASP.NET Applicationhttp://support.microsoft.com/default.aspx?scid=kb;en-us;Q306158&SD=MSKB2. INFO: ASP.NET Security Overviewhttp://support.microsoft.com/default.aspx?scid=kb;en-us;Q3065903. ASP.NET Web Application Securityhttp://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconaspnetwebapplicationsecurity.asp作者:黃雪斌