asp.net身份模擬

下面介紹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" />
模擬IIS認證帳號
這是最簡單的一種方法,使用經過IIS認證的帳號執行應用程序。您需要在Web.config文件中添加<identity>標記,並將impersonate屬性設置爲true:
<identity impersonate="true" />
在這種情況下,用戶身份的認證交給IIS來進行。
當允許匿名登錄時,IIS將一個匿名登錄使用的標識(缺省
情況下是IUSR_MACHINENAME)交給ASP.NET應用程序。當不允許匿名登錄時,IIS將認證過的身份標識傳遞給ASP.NET應用程序。ASP.NET的具體訪問權限由該賬號的權限決定。
在代碼中模擬IIS認證帳號
在代碼中使用身份模擬更加靈活,可以在指定的代碼段中使用身份模擬,在該代碼段之外恢復使用ASPNET本機帳號。該方法要求必須使用Windows的認證身份標識。下面的例子在代碼中模擬IIS認證帳號:
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 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 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 Integer
Declare Auto Function DuplicateToken Lib "advapi32.dll"(ByVal ExistingTokenHandle As IntPtr, _
                           ImpersonationLevel As Integer, _
                           ByRef DuplicateTokenHandle As IntPtr) As Integer

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

Private Function impersonateValidUser(userName As String, _
domain As String, password As String) As Boolean 
   Dim tempWindowsIdentity As WindowsIdentity
   Dim token As IntPtr
   Dim tokenDuplicate As IntPtr

   If LogonUser(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 impersonationContext Is Nothing Then
                   impersonateValidUser = False
                Else
    	           impersonateValidUser = True
                End If
      Else
	        impersonateValidUser = False
      End If
   Else
      impersonateValidUser = False
   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", 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;
         else
            return false; 
      }
      else
         return false;
   } 
   else
      return false;
}
private void undoImpersonation()
{
     impersonationContext.Undo();
} 
</script>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章