如何在 ASP.NET 應用程序中實現模擬用戶身份(在ASP.NET中以管理員身份運行網站)


前言

在實際的項目開發中,我們可能會需要調用一些非托管程序,而有些非托管程序需要有更高的身份權限才能正確執行。本文介紹了如何讓IIS承載的ASP.NET網站以特定的賬戶執行,比如Administrator。

概要

本文介紹了在 ASP.NET 應用程序中實現模擬用戶身份的不同方式。

更多信息

如果要在 ASP.NET 中的線程上模擬用戶,可以根據您的要求使用以下方法之一:

  • 模擬 IIS 驗證的帳戶或用戶
  • 為 ASP.NET 應用程序的所有請求模擬特定用戶
  • 在代碼中模擬身份驗證用戶
  • 在代碼中模擬特定用戶

注意:可以使用以下代碼來確定線程作為哪個用戶執行:

System.Security.Principal.WindowsIdentity.GetCurrent().Name

 模擬 IIS 驗證的帳戶或用戶

若要在收到 ASP.NET 應用程序中每個頁的每個請求時模擬 Microsoft Internet 信息服務 (IIS) 身份驗證用戶,必須在此應用程序的 Web.config 文件中包含 <identity> 標記,並將 impersonate 屬性設置為 true。例如:

<identity impersonate="true" />

 為 ASP.NET 應用程序的所有請求模擬特定用戶

若要為 ASP.NET 應用程序的所有頁面上的所有請求模擬特定用戶,可以在該應用程序的 Web.config 文件的 <identity> 標記中指定 userNamepassword 屬性。例如:

<identity impersonate="true" userName="accountname" password="password" />

在代碼中模擬身份驗證用戶

若要僅在運行代碼的特定部分時模擬身份驗證用戶 (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();
                

在代碼中模擬特定用戶

若要僅在運行代碼的特定部分時模擬特定用戶,請使用以下代碼:

<%@ 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 Basic .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 C# .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>
            
Visual J# .NET


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM