title: impersonation and BackgroundWorker
body: <p>I have a little bit of a problem when trying to use the <code>BackgroundWorker</code> class with impersonation. Following the answers from Google, I got this code to impersonate</p>
  
  <pre><code>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;
      }
  }
  </code></pre>
  
  <p>It worked really well until I used it with the <code>BackgroundWorker</code> 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.</p>
  
  <p>In code this looks something like this:</p>
  
  <ul>
  <li><p>instantiate a BGWorker, and add an event handler to the DoWork event:</p>
  
  <pre><code>_bgWorker = new BackgroundWorker();
  _bgWorker.DoWork += new DoWorkEventHandler(_bgWorker_DoWork);
  </code></pre></li>
  <li><p>in the above handler, a impersonation is made before running some code.</p>
  
  <pre><code>private void _bgWorker_DoWork(object sender, DoWorkEventArgs e) {        
          MyImpersonation myImpersonation = new MyImpersonation();
          myImpersonation.impersonateValidUser(user, domain, pass)        
         //run some code...        
         myImpersonation.undoImpersonation();        
  }
  </code></pre></li>
  <li><p>the code is launched with </p>
  
  <pre><code>BGWorker.RunWorkerAsync();
  </code></pre></li>
  </ul>
  
  <p>As I said before, no error is thrown, only that the code acts as if I didn't run any impersonation, that is with its default credentials.</p>
  
  <p>Moreover, the impersonation method returns true, so the impersonation took place at a certain level, but probably not on the current thread.</p>
  
  <p>This must happen because the async code runs on another thread, so there must be something that needs to be added to the <code>MyImpersonation</code> class. But what? :)</p>