impersonation and BackgroundWorker

Posted by Lucian D on Stack Overflow See other posts from Stack Overflow or by Lucian D
Published on 2009-04-08T16:23:11Z Indexed on 2010/04/13 11:03 UTC
Read the original article Hit count: 583

Hello guys,

I have a little bit of a problem when trying to use the BackgroundWorker class with impersonation. Following the answers from google, I got this code to impersonate

public class MyImpersonation{

    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 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;
        	}
}

It worked really well until I've used it with the BackgroundWorker class. In this case, I've added a impersonation in the the code that runs asynchronously. I have no errors, but the issue I'm having is that the impersonation does not work when it is used in the async method.

In code this looks something like this:

  • instantiate a BGWorker, and add an event handler to the DoWork event:

    _bgWorker = new BackgroundWorker(); _bgWorker.DoWork += new DoWorkEventHandler(_bgWorker_DoWork);

  • in the above handler, a impersonation is made before running some code.

    private void _bgWorker_DoWork(object sender, DoWorkEventArgs e) {
    MyImpersonation myImpersonation = new MyImpersonation(); myImpersonation.impersonateValidUser(user, domain, pass)
    //run some code...
    myImpersonation.undoImpersonation();
    }

  • the code is launched with

    BGWorker.RunWorkerAsync();

As I said before, no error is thrown, only that the code acts as if I did't run any impersonation, that is with it's default credentials. Moreover, the impersonation method returns true, so the impersonation took place at a certain level, but probably not on the current thread. This must happen because the async code runs on another thread, so there must be something that needs to be added to the MyImpersonation class. But what?? :)

Thanks in advance, Lucian

© Stack Overflow or respective owner

Related posts about impersonation

Related posts about backgroundworker