views:

315

answers:

1

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

A: 

I'm having this same problem. I have a background worker that does impersonation with a static class in the DoWork event. I'm attempting to impersonate another Active Domain user in order to read a directory that the main user does not have access to. If I am running the application in the IDE, the impersonated user can read the files with no problem. If I run the application from the file system, the impersonation still happens, but an exception is thrown saying the impersonated user does not have access.

From what I've read it's due to setting Assembly:SecurityPermissionAttribute and Assembly:PermissionSetAttribute.

Before the class declaration I have the following:

    <Assembly: SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode:=True), _
Assembly: PermissionSetAttribute(SecurityAction.RequestMinimum, Name:="FullTrust")>

Before my StartImpersonating() function, I have:

<PermissionSetAttribute(SecurityAction.Demand, Name:="FullTrust")> _

I'm working with VB.NET and not C#, however.

-D