Welcome to MSDN Blogs Sign in | Join | Help

Impersonation code in C#

While investigating a customer issue, I needed code to impersonate a different user on the current thread.  A quick search of the msdn blogs turned up this post, which got me most of the way there.  I decided to wrap the code into a class that inherits from IDisposable just to make it easily usable in a using statement.  Here is what I came up with (note that it is not thread safe):

using System;

using System.ComponentModel;

using System.Runtime.InteropServices;

using System.Security.Principal;

 

public class ImpersonatedUser : IDisposable

{

    IntPtr userHandle;

    WindowsImpersonationContext impersonationContext;

 

    public ImpersonatedUser(string user, string domain, string password)

    {

        userHandle = IntPtr.Zero;

        bool loggedOn = LogonUser(

            user,

            domain,

            password,

            LogonType.Interactive,

            LogonProvider.Default,

            out userHandle);

 

        if (!loggedOn)

            throw new Win32Exception(Marshal.GetLastWin32Error());

 

        // Begin impersonating the user

        impersonationContext = WindowsIdentity.Impersonate(userHandle);

    }

 

    public void Dispose()

    {

        if (userHandle != IntPtr.Zero)

        {

            CloseHandle(userHandle);

            userHandle = IntPtr.Zero;

            impersonationContext.Undo();

        }

    } 

 

    [DllImport("advapi32.dll", SetLastError = true)]

    static extern bool LogonUser(

        string lpszUsername,

        string lpszDomain,

        string lpszPassword,

        LogonType dwLogonType,

        LogonProvider dwLogonProvider,

        out IntPtr phToken

        );

 

    [DllImport("kernel32.dll", SetLastError = true)]

    static extern bool CloseHandle(IntPtr hHandle);

 

    enum LogonType : int

    {

        Interactive = 2,

        Network = 3,

        Batch = 4,

        Service = 5,

        NetworkCleartext = 8,

        NewCredentials = 9,

    }

 

    enum LogonProvider : int

    {

        Default = 0,

    }

}

Published Monday, September 21, 2009 1:06 PM by joncole
Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

Monday, September 21, 2009 4:56 PM by Gareth

# re: Impersonation code in C#

Would I be right in saying that as the ImpersonatedUser class does not have a finalizer there is no pint in calling "GC.SuppressFinalize(this);"? And there would be no point in adding a finalizer as it would run on a different thread?

Monday, September 21, 2009 6:04 PM by joncole

# re: Impersonation code in C#

Gareth,

I believe you are right about the SuppressFinalize call.  I pounded this code out pretty quickly and didn't consider that fact.  I have removed the unnecssary code.  Thanks for the comment.

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
 
Page view tracker