Auf Englisch lesen

Freigeben über


WindowsIdentity.Impersonate Methode

Definition

Ermöglicht es, im Code die Identität eines anderen Windows-Benutzers anzunehmen.

Überlädt

Impersonate()

Nimmt die Identität des durch das WindowsIdentity-Objekt dargestellten Benutzers an.

Impersonate(IntPtr)

Nimmt die Identität des durch das angegebene Benutzertoken dargestellten Benutzers an.

Impersonate()

Nimmt die Identität des durch das WindowsIdentity-Objekt dargestellten Benutzers an.

public virtual System.Security.Principal.WindowsImpersonationContext Impersonate();

Gibt zurück

Ein Objekt, das den Windows-Benutzer vor dem Identitätswechsel darstellt. Es kann dazu verwendet werden, in den Kontext des ursprünglichen Benutzers zurückzukehren.

Ausnahmen

Eine anonyme Identität hat versucht, einen Identitätswechsel durchzuführen.

Win32-Fehler.

Beispiele

Im folgenden Beispiel wird veranschaulicht, wie Sie ein Windows-Kontotoken durch Aufrufen der nicht verwalteten Win32-Funktion LogonUser abrufen und dieses Token verwenden, um die Identität eines anderen Benutzers zu annehmen und dann zur ursprünglichen Identität zurückzugeben.

// This sample demonstrates the use of the WindowsIdentity class to impersonate a user.
// IMPORTANT NOTES:
// This sample requests the user to enter a password on the console screen.
// Because the console window does not support methods allowing the password to be masked,
// it will be visible to anyone viewing the screen.
// On Windows Vista and later this sample must be run as an administrator.

using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles;
using System.Runtime.ConstrainedExecution;
using System.Security;

public class ImpersonationDemo
{
    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
        int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public extern static bool CloseHandle(IntPtr handle);

    // Test harness.
    // If you incorporate this code into a DLL, be sure to demand FullTrust.
    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
    public static void Main(string[] args)
    {
        SafeTokenHandle safeTokenHandle;
        try
        {
            string userName, domainName;
            // Get the user token for the specified user, domain, and password using the
            // unmanaged LogonUser method.
            // The local machine name can be used for the domain name to impersonate a user on this machine.
            Console.Write("Enter the name of the domain on which to log on: ");
            domainName = Console.ReadLine();

            Console.Write("Enter the login of a user on {0} that you wish to impersonate: ", domainName);
            userName = Console.ReadLine();

            Console.Write("Enter the password for {0}: ", userName);

            const int LOGON32_PROVIDER_DEFAULT = 0;
            //This parameter causes LogonUser to create a primary token.
            const int LOGON32_LOGON_INTERACTIVE = 2;

            // Call LogonUser to obtain a handle to an access token.
            bool returnValue = LogonUser(userName, domainName, Console.ReadLine(),
                LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                out safeTokenHandle);

            Console.WriteLine("LogonUser called.");

            if (false == returnValue)
            {
                int ret = Marshal.GetLastWin32Error();
                Console.WriteLine("LogonUser failed with error code : {0}", ret);
                throw new System.ComponentModel.Win32Exception(ret);
            }
            using (safeTokenHandle)
            {
                Console.WriteLine("Did LogonUser Succeed? " + (returnValue ? "Yes" : "No"));
                Console.WriteLine("Value of Windows NT token: " + safeTokenHandle);

                // Check the identity.
                Console.WriteLine("Before impersonation: "
                    + WindowsIdentity.GetCurrent().Name);
                // Use the token handle returned by LogonUser.
                using (WindowsIdentity newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle()))
                {
                    using (WindowsImpersonationContext impersonatedUser = newId.Impersonate())
                    {

                        // Check the identity.
                        Console.WriteLine("After impersonation: "
                            + WindowsIdentity.GetCurrent().Name);
                    }
                }
                // Releasing the context object stops the impersonation
                // Check the identity.
                Console.WriteLine("After closing the context: " + WindowsIdentity.GetCurrent().Name);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception occurred. " + ex.Message);
        }
    }
}
public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
    private SafeTokenHandle()
        : base(true)
    {
    }

    [DllImport("kernel32.dll")]
    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
    [SuppressUnmanagedCodeSecurity]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool CloseHandle(IntPtr handle);

    protected override bool ReleaseHandle()
    {
        return CloseHandle(handle);
    }
}

Hinweise

Auf Windows NT-Plattformen muss der aktuelle Benutzer über ausreichende Rechte verfügen, um den Identitätswechsel zuzulassen.

Warnung

Vermeiden Sie die Verwendung dieser Methode mit dem Muster async/await. In einigen Fällen kann dies zu Zuverlässigkeitsproblemen führen, da der Identitätswechsel nicht wiederhergestellt wird, selbst wenn das resultierende WindowsImpersonationContext gelöscht wird. Verwenden Sie stattdessen RunImpersonated.

Hinweise für Aufrufer

Nach der Verwendung Impersonate()von ist es wichtig, die Undo() -Methode aufzurufen, um den Identitätswechsel zu beenden.

Gilt für:

.NET Framework 4.8.1 und andere Versionen
Produkt Versionen
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1

Impersonate(IntPtr)

Nimmt die Identität des durch das angegebene Benutzertoken dargestellten Benutzers an.

public static System.Security.Principal.WindowsImpersonationContext Impersonate(IntPtr userToken);

Parameter

userToken
IntPtr

Das Handle eines Windows-Kontotokens. Dieses Token wird normalerweise durch einen Aufruf von nicht verwaltetem Code abgerufen, z. B. durch einen Aufruf der LogonUser-Funktion der Windows-API.

Gibt zurück

Ein Objekt, das den Windows-Benutzer vor dem Identitätswechsel darstellt. Es kann dazu verwendet werden, in den Kontext des ursprünglichen Benutzers zurückzukehren.

Ausnahmen

Windows hat den Windows NT-Statuscode STATUS_ACCESS_DENIED zurückgegeben.

Es ist nicht genügend Arbeitsspeicher verfügbar.

Der Aufrufer verfügt nicht über die ordnungsgemäßen Berechtigungen.

Beispiele

Im folgenden Beispiel wird veranschaulicht, wie Sie ein Windows-Kontotoken durch Aufrufen der nicht verwalteten Win32-Funktion LogonUser abrufen und dieses Token verwenden, um die Identität eines anderen Benutzers zu annehmen und dann zur ursprünglichen Identität zurückzugeben.

// This sample demonstrates the use of the WindowsIdentity class to impersonate a user.
// IMPORTANT NOTES:
// This sample requests the user to enter a password on the console screen.
// Because the console window does not support methods allowing the password to be masked,
// it will be visible to anyone viewing the screen.
// On Windows Vista and later this sample must be run as an administrator.

using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles;
using System.Runtime.ConstrainedExecution;
using System.Security;

public class ImpersonationDemo
{
    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
        int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public extern static bool CloseHandle(IntPtr handle);

    // Test harness.
    // If you incorporate this code into a DLL, be sure to demand FullTrust.
    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
    public static void Main(string[] args)
    {
        SafeTokenHandle safeTokenHandle;
        try
        {
            string userName, domainName;
            // Get the user token for the specified user, domain, and password using the
            // unmanaged LogonUser method.
            // The local machine name can be used for the domain name to impersonate a user on this machine.
            Console.Write("Enter the name of the domain on which to log on: ");
            domainName = Console.ReadLine();

            Console.Write("Enter the login of a user on {0} that you wish to impersonate: ", domainName);
            userName = Console.ReadLine();

            Console.Write("Enter the password for {0}: ", userName);

            const int LOGON32_PROVIDER_DEFAULT = 0;
            //This parameter causes LogonUser to create a primary token.
            const int LOGON32_LOGON_INTERACTIVE = 2;

            // Call LogonUser to obtain a handle to an access token.
            bool returnValue = LogonUser(userName, domainName, Console.ReadLine(),
                LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                out safeTokenHandle);

            Console.WriteLine("LogonUser called.");

            if (false == returnValue)
            {
                int ret = Marshal.GetLastWin32Error();
                Console.WriteLine("LogonUser failed with error code : {0}", ret);
                throw new System.ComponentModel.Win32Exception(ret);
            }
            using (safeTokenHandle)
            {
                Console.WriteLine("Did LogonUser Succeed? " + (returnValue ? "Yes" : "No"));
                Console.WriteLine("Value of Windows NT token: " + safeTokenHandle);

                // Check the identity.
                Console.WriteLine("Before impersonation: "
                    + WindowsIdentity.GetCurrent().Name);
                // Use the token handle returned by LogonUser.
                using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(safeTokenHandle.DangerousGetHandle()))
                {

                    // Check the identity.
                    Console.WriteLine("After impersonation: "
                        + WindowsIdentity.GetCurrent().Name);
                }
                // Releasing the context object stops the impersonation
                // Check the identity.
                Console.WriteLine("After closing the context: " + WindowsIdentity.GetCurrent().Name);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception occurred. " + ex.Message);
        }
    }
}
public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
    private SafeTokenHandle()
        : base(true)
    {
    }

    [DllImport("kernel32.dll")]
    [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
    [SuppressUnmanagedCodeSecurity]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool CloseHandle(IntPtr handle);

    protected override bool ReleaseHandle()
    {
        return CloseHandle(handle);
    }
}

Hinweise

Auf Windows NT-Plattformen muss der aktuelle Benutzer über ausreichende Rechte verfügen, um den Identitätswechsel zuzulassen.

Hinweis

Das Aufrufen der Impersonate(IntPtr) -Methode mit dem userToken Wert von Zero entspricht dem Aufrufen der Win32-Funktion RevertToSelf . Wenn zurzeit ein anderer Benutzer die Identität angibt, wird das Steuerelement auf den ursprünglichen Benutzer zurückgesetzt.

Weitere Informationen zu Aufrufen von nicht verwaltetem Code finden Sie unter Verwenden von nicht verwalteten DLL-Funktionen.

Warnung

Vermeiden Sie die Verwendung dieser Methode mit dem Muster async/await. In einigen Fällen kann dies zu Zuverlässigkeitsproblemen führen, da der Identitätswechsel nicht wiederhergestellt wird, selbst wenn das resultierende WindowsImpersonationContext gelöscht wird. Verwenden Sie stattdessen RunImpersonated.

Hinweise für Aufrufer

Nach der Verwendung Impersonate(IntPtr)von ist es wichtig, die Undo() -Methode aufzurufen, um den Identitätswechsel zu beenden.

Gilt für:

.NET Framework 4.8.1 und andere Versionen
Produkt Versionen
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1