Impersonate Method (IntPtr)
Collapse the table of content
Expand the table of content

WindowsIdentity.Impersonate Method (IntPtr)


Impersonates the user represented by the specified user token.

Namespace:   System.Security.Principal
Assembly:  mscorlib (in mscorlib.dll)

[SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.NoFlags | SecurityPermissionFlag.UnmanagedCode | SecurityPermissionFlag.ControlPrincipal)]
public static WindowsImpersonationContext Impersonate(
	IntPtr userToken


Type: System.IntPtr

The handle of a Windows account token. This token is usually retrieved through a call to unmanaged code, such as a call to the Win32 API LogonUser function.

Return Value

Type: System.Security.Principal.WindowsImpersonationContext

An object that represents the Windows user prior to impersonation; this object can be used to revert to the original user's context.

Exception Condition

Windows returned the Windows NT status code STATUS_ACCESS_DENIED.


There is insufficient memory available.


The caller does not have the correct permissions.

On Windows NT platforms, the current user must have sufficient rights to allow impersonation.


Calling the Impersonate(IntPtr) method with a userToken value of Zero is equivalent to calling the Win32 RevertToSelf function. If another user is currently being impersonated, control reverts to the original user.

For more information about calls to unmanaged code, see Consuming Unmanaged DLL Functions.

Notes to Implementers:

Because Microsoft Windows 98 and Windows Millennium Edition (Windows Me) platforms do not have user tokens, impersonation cannot take place on those platforms.

Notes to Callers:

After using Impersonate, it is important to call the Undo method to end the impersonation.

The following example demonstrates how to obtain a Windows account token by calling the unmanaged Win32 LogonUser function, and how to use that token to impersonate another user and then revert to the original identity.

// This sample demonstrates the use of the WindowsIdentity class to impersonate a user.
// 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;
            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(),
                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)

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

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


for the ability to manipulate the principal object and access unmanaged code. Associated enumerations: SecurityPermissionFlag.ControlPrincipal and SecurityPermissionFlag.UnmanagedCode

.NET Framework
Available since 1.1
Return to top
© 2015 Microsoft