Replace Current Windows User Running the EXE with

2019-02-20 18:26发布

问题:

Say if I built a windows application that reads files from a network folder. The network folds restrict the access to only one user "fooUser". The application is installed in several machines on the network.

I need to replace the current user with "fooUser" in order to be able to access the files on the network folder by code.

回答1:

Here is a very simple impersonation scheme that will let you be anyone for a shot period (granted you have the appropriate credentials.)
This class will do all of the heavy lifting for you....

  public class Impersonator : IDisposable
  {

    const int LOGON32_PROVIDER_DEFAULT = 0;
    const int LOGON32_LOGON_INTERACTIVE = 2;

    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public extern static bool CloseHandle(IntPtr handle);

    private IntPtr token = IntPtr.Zero;
    private WindowsImpersonationContext impersonated;
    private readonly string _ErrMsg = "";

    public bool IsImpersonating
    {
      get { return (token != IntPtr.Zero) && (impersonated != null); }
    }

    public string ErrMsg
    {
      get { return _ErrMsg; }
    }

    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
    public Impersonator(string userName, string password, string domain)
    {
      StopImpersonating();

      bool loggedOn = LogonUser(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token);
      if (!loggedOn)
      {
        _ErrMsg = new System.ComponentModel.Win32Exception().Message;
        return;
      }

      WindowsIdentity identity = new WindowsIdentity(token);
      impersonated = identity.Impersonate();
    }

    private void StopImpersonating()
    {
      if (impersonated != null)
      {
        impersonated.Undo();
        impersonated = null;
      }

      if (token != IntPtr.Zero)
      {
        CloseHandle(token);
        token = IntPtr.Zero;
      }
    }

    public void Dispose()
    {
      StopImpersonating();
    }
  }

And you can use it like so;

using (Impersonator = new Impersonator(yourName,yourPassword,yourDomain))
{
 // Read files from network drives.
 // Other activities....
}

It is very important to place the impersonator in the 'using' block, or to dispose it when you are done doing your impersonated tasks, or the system will continue to impersonate indefinitely, which will cause all kinds of problems.



回答2:

use the runas utility: http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/runas.mspx?mfr=true

Hope this helps.



回答3:

You can check if this question LogonUser and delegation would help you.



回答4:

You could just set up a mapped drive to the folder share that uses the 'fooUser' credentials.

Though if you have the login/password for the user you can get your code to use impersonation. As per my answer to Windows Impersonation from C# :

For the Impersonation code see the following two Code Project articles:

http://www.codeproject.com/KB/cs/cpimpersonation1.aspx

http://www.codeproject.com/KB/cs/zetaimpersonator.aspx

and the Microsoft KB article they are based upon:

http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306158