Imitatie implementeren in een ASP.NET-toepassing

In dit artikel worden verschillende manieren beschreven om imitatie in een ASP.NET toepassing te implementeren.

Oorspronkelijke productversie: ASP.NET
Origineel KB-nummer: 306158

Samenvatting

In dit artikel wordt uitgelegd hoe u imitatie implementeert door het Web.config-bestand te wijzigen en een bepaalde sectie met code uit te voeren.

Het verwijst naar de volgende Microsoft .NET Framework Class Library-naamruimten:

  • System.Web.Security
  • System.Security.Principal
  • System.Runtime.InteropServices

U kunt de volgende code gebruiken om te bepalen welke gebruiker de thread uitvoert als:

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

Door IIS geverifieerd account of gebruiker imiteren

Als u de internetinformatieservices (IIS)-verificatiegebruiker voor elke aanvraag voor elke pagina in een ASP.NET-toepassing wilt imiteren, moet u een <identity> tag opnemen in het Web.config-bestand van deze toepassing en het kenmerk imiteren instellen op true. Bijvoorbeeld:

<identity impersonate="true" />

Een specifieke gebruiker imiteren voor alle aanvragen van een ASP.NET-toepassing

Als u een specifieke gebruiker wilt imiteren voor alle aanvragen op alle pagina's van een ASP.NET toepassing, kunt u de userName kenmerken en password opgeven in de <identity> tag van het Web.config-bestand voor die toepassing. Bijvoorbeeld:

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

Opmerking

De identiteit van het proces dat een specifieke gebruiker in een thread imiteert, moet acteren als onderdeel van de bevoegdheid van het besturingssysteem hebben. Standaard wordt het Aspnet_wp.exe proces uitgevoerd onder een computeraccount met de naam ASPNET. Dit account heeft echter niet de vereiste bevoegdheden om een specifieke gebruiker te imiteren. U ontvangt een foutbericht als u een specifieke gebruiker probeert te imiteren. Deze informatie is alleen van toepassing op de .NET Framework 1.0. Deze bevoegdheid is niet vereist voor de .NET Framework 1.1.

Gebruik een van de volgende methoden om dit probleem te omzeilen:

  • Ververleent act als onderdeel van de besturingssysteembevoegdheden aan het ASPNET-account (het account met de minste bevoegdheden).

    Opmerking

    Hoewel u deze methode kunt gebruiken om het probleem te omzeilen, raadt Microsoft deze methode niet aan.

  • Wijzig het account waaronder het Aspnet_wp.exe proces wordt uitgevoerd in het systeemaccount in de <processModel> configuratiesectie van het Machine.config-bestand.

De verifiërende gebruiker in code imiteren

Als u de verifiërende gebruiker (User.Identity) alleen wilt imiteren wanneer u een bepaalde codesectie uitvoert, kunt u de code gebruiken om te volgen. Deze methode vereist dat de verifiërende gebruikersidentiteit van het type WindowsIdentityis.

  • 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();
    

Een specifieke gebruiker in code imiteren

Als u een specifieke gebruiker alleen wilt imiteren wanneer u een bepaalde sectie met code uitvoert, gebruikt u de volgende code:

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>

De identiteit van het proces dat een specifieke gebruiker in een thread imiteert, moet de bevoegdheid Act as part of the operating system hebben als het Aspnet_wp.exe proces wordt uitgevoerd op een computer met Windows 2000. De bevoegdheid Act as part of the operating system is niet vereist als het Aspnet_wp.exe proces wordt uitgevoerd op een Windows XP-computer of op een computer met Windows Server 2003. Standaard wordt het Aspnet_wp.exe proces uitgevoerd onder een computeraccount met de naam ASPNET. Dit account heeft echter niet de vereiste bevoegdheden om een specifieke gebruiker te imiteren. U ontvangt een foutbericht als u een specifieke gebruiker probeert te imiteren.

Gebruik een van de volgende methoden om dit probleem te omzeilen:

  • Ververleent act als onderdeel van de besturingssysteembevoegdheden aan het ASPNET-account.

    Opmerking

    We raden deze methode niet aan om het probleem te omzeilen.

  • Wijzig het account waaronder het Aspnet_wp.exe proces wordt uitgevoerd in het systeemaccount in de <processModel> configuratiesectie van het Machine.config-bestand.

Verwijzingen

ASP.NET beveiligingsoverzicht