Click here to Skip to main content
15,174,536 members
Articles / Programming Languages / C#
Posted 29 Apr 2003


149 bookmarked

Windows Impersonation using C#

Rate me:
Please Sign up or sign in to vote.
4.77/5 (49 votes)
29 Apr 2003CPOL
An article demonstrating how to use Windows impersonation in your C# code



I've been a member of the CodeProject for over 3 years now, and still haven't contributed any articles - until now.

While designing a Windows Forms-based application, to administrate containers in our Active Directory, I needed a way to allow binding to the AD using alternate credentials. Windows impersonation was the answer. This sample app demonstrates how to use unmanaged code by calling LogonUser() contained within the advapi32.dll, and pass a token handle back to your .NET application using WindowsImpersonationContext.

One of the downfalls to the LogonUser()function is that the password get passed in clear-text.

Partial Source Code

using System.Runtime.InteropServices; // DllImport
using System.Security.Principal; // WindowsImpersonationContext
using System.Security.Permissions; // PermissionSetAttribute

public WindowsImpersonationContext 
    ImpersonateUser(string sUsername, string sDomain, string sPassword)
    // initialize tokens
    IntPtr pExistingTokenHandle = new IntPtr(0);
    IntPtr pDuplicateTokenHandle = new IntPtr(0);
    pExistingTokenHandle = IntPtr.Zero;
    pDuplicateTokenHandle = IntPtr.Zero;
    // if domain name was blank, assume local machine
    if (sDomain == "")
        sDomain = System.Environment.MachineName;

        string sResult = null;

        const int LOGON32_PROVIDER_DEFAULT = 0;

        // create token
        const int LOGON32_LOGON_INTERACTIVE = 2;
        //const int SecurityImpersonation = 2;

        // get handle to token
        bool bImpersonated = LogonUser(sUsername, sDomain, sPassword, 
                ref pExistingTokenHandle);

        // did impersonation fail?
        if (false == bImpersonated)
            int nErrorCode = Marshal.GetLastWin32Error();
            sResult = "LogonUser() failed with error code: " + 
                nErrorCode + "\r\n";

            // show the reason why LogonUser failed
            MessageBox.Show(this, sResult, "Error", 
                MessageBoxButtons.OK, MessageBoxIcon.Error);

        // Get identity before impersonation
        sResult += "Before impersonation: " + 
            WindowsIdentity.GetCurrent().Name + "\r\n";

        bool bRetVal = DuplicateToken(pExistingTokenHandle, 
                ref pDuplicateTokenHandle);

        // did DuplicateToken fail?
        if (false == bRetVal)
            int nErrorCode = Marshal.GetLastWin32Error();
            // close existing handle
            sResult += "DuplicateToken() failed with error code: " 
                + nErrorCode + "\r\n";

            // show the reason why DuplicateToken failed
            MessageBox.Show(this, sResult, "Error", 
                MessageBoxButtons.OK, MessageBoxIcon.Error);
            return null;
            // create new identity using new primary token
            WindowsIdentity newId = new WindowsIdentity
            WindowsImpersonationContext impersonatedUser = 

            // check the identity after impersonation
            sResult += "After impersonation: " + 
                WindowsIdentity.GetCurrent().Name + "\r\n";
            MessageBox.Show(this, sResult, "Success", 
                MessageBoxButtons.OK, MessageBoxIcon.Information);
            return impersonatedUser;
    catch (Exception ex)
        throw ex;
        // close handle(s)
        if (pExistingTokenHandle != IntPtr.Zero)
        if (pDuplicateTokenHandle != IntPtr.Zero) 

Points of Interest

This code won't work on Windows 98 or ME because they do not utilize user tokens. Code was built and run using Visual Studio.NET 2002 on Windows XP Service Pack 1.

One of the other uses for this code I've found is, for instantiating COM components that must run in an alternate security context to that of the logged-on user.

If anyone has a more secure method of achieving the same thing, please let me know.


  • Version 1.0 - 04.25.03 - First release version


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Christian Merritt
Chief Technology Officer
Australia Australia
Living abroad and loving life.

Comments and Discussions

GeneralImpersonation Pin
chriskoiak16-Mar-04 6:13
Memberchriskoiak16-Mar-04 6:13 
QuestionRe: Impersonation Pin
tee_jay10-Apr-06 23:08
Membertee_jay10-Apr-06 23:08 
AnswerRe: Impersonation Pin
Harkamal Singh12-Jul-07 20:01
MemberHarkamal Singh12-Jul-07 20:01 
GeneralRe: Impersonation Pin
Phutphornxai19-Jul-07 2:43
MemberPhutphornxai19-Jul-07 2:43 
GeneralCoding Style Issues Pin
Andy Neilson7-May-03 3:56
MemberAndy Neilson7-May-03 3:56 
GeneralRe: Coding Style Issues Pin
Maximilian Hänel27-May-03 13:54
MemberMaximilian Hänel27-May-03 13:54 
GeneralRe: Coding Style Issues Pin
Andy Neilson28-May-03 3:53
MemberAndy Neilson28-May-03 3:53 
GeneralRe: Coding Style Issues Pin
Maximilian Hänel28-May-03 5:56
MemberMaximilian Hänel28-May-03 5:56 
Andy Neilson wrote:
I understand the difference between the two forms of throw statement

I don't doubt that, Andy! I only wanted to emphasise the difference in the context of the article.

Andy Neilson wrote:
but I don't see why that catch clause is there at all

The only one who knows is probably the author itself... Wink | ;-)


"You can always improve your chances of writing
bug-free code by writing code that doesn't do anything"

Rob Macdonald, Serious ADO

GeneralJust to complete this Pin
Jahava25-Oct-03 5:53
MemberJahava25-Oct-03 5:53 
GeneralRe: Just to complete this Pin
Christian Merritt25-Oct-03 9:42
MemberChristian Merritt25-Oct-03 9:42 
GeneralWhat an attitude... Pin
Jahava27-Oct-03 6:08
MemberJahava27-Oct-03 6:08 
GeneralRe: What an attitude... Pin
Christian Merritt27-Oct-03 6:46
MemberChristian Merritt27-Oct-03 6:46 
GeneralIt's cool Pin
Jahava27-Oct-03 14:45
MemberJahava27-Oct-03 14:45 
GeneralRe: Coding Style Issues Pin
Jonathan C Dickinson5-May-08 2:53
MemberJonathan C Dickinson5-May-08 2:53 
GeneralError messages Pin
Maximilian Hänel6-May-03 2:24
MemberMaximilian Hänel6-May-03 2:24 
GeneralRe: Error messages Pin
Haidong Chen27-May-03 13:15
MemberHaidong Chen27-May-03 13:15 
GeneralRe: Error messages Pin
Haidong Chen27-May-03 13:17
MemberHaidong Chen27-May-03 13:17 
GeneralRe: Error messages Pin
Maximilian Hänel27-May-03 13:47
MemberMaximilian Hänel27-May-03 13:47 
GeneralSeImpersonatePrivilege Pin
geo_m3-May-03 23:56
Membergeo_m3-May-03 23:56 
GeneralThis method won't work on Windows 2000 or Windows NT Pin
Softomatix3-May-03 14:54
MemberSoftomatix3-May-03 14:54 
GeneralRe: This method won't work on Windows 2000 or Windows NT Pin
Christian Merritt3-May-03 16:53
MemberChristian Merritt3-May-03 16:53 
GeneralRe: This method won't work on Windows 2000 or Windows NT Pin
Softomatix4-May-03 4:57
MemberSoftomatix4-May-03 4:57 
GeneralRe: This method won't work on Windows 2000 or Windows NT Pin
Danko Greiner14-Dec-04 1:44
MemberDanko Greiner14-Dec-04 1:44 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.