C#: How to logon to a share when using DirectoryInfo

后端 未结 2 1008
予麋鹿
予麋鹿 2020-12-03 08:28

If I want to instantiate a DirectoryInfo object with an UNC path

DirectoryInfo myDI = new DirectoryInfo (@\"\\\\server\\share\");

how can

2条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-03 09:08

    Try this approach:

    using System;
    using System.ComponentModel;
    using System.Runtime.InteropServices;
    using System.Security.Principal;
    
    namespace Tools.Network
    {
     public enum LogonType
     {
      LOGON32_LOGON_INTERACTIVE = 2,
      LOGON32_LOGON_NETWORK = 3,
      LOGON32_LOGON_BATCH = 4,
      LOGON32_LOGON_SERVICE = 5,
      LOGON32_LOGON_UNLOCK = 7,
      LOGON32_LOGON_NETWORK_CLEARTEXT = 8, // Win2K or higher
      LOGON32_LOGON_NEW_CREDENTIALS = 9 // Win2K or higher
     };
    
     public enum LogonProvider
     {
      LOGON32_PROVIDER_DEFAULT = 0,
      LOGON32_PROVIDER_WINNT35 = 1,
      LOGON32_PROVIDER_WINNT40 = 2,
      LOGON32_PROVIDER_WINNT50 = 3
     };
    
     public enum ImpersonationLevel
     {
      SecurityAnonymous = 0,
      SecurityIdentification = 1,
      SecurityImpersonation = 2,
      SecurityDelegation = 3
     }
    
     class Win32NativeMethods
     {
      [DllImport("advapi32.dll", SetLastError = true)]
      public static extern int LogonUser( 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);
     }
    
     /// 
     /// Allows code to be executed under the security context of a specified user account.
     /// 
     ///  
     ///
     /// Implements IDispose, so can be used via a using-directive or method calls;
     ///  ...
     ///
     ///  var imp = new Impersonator( "myUsername", "myDomainname", "myPassword" );
     ///  imp.UndoImpersonation();
     ///
     ///  ...
     ///
     ///   var imp = new Impersonator();
     ///  imp.Impersonate("myUsername", "myDomainname", "myPassword");
     ///  imp.UndoImpersonation();
     ///
     ///  ...
     ///
     ///  using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
     ///  {
     ///   ...
     ///   [code that executes under the new context]
     ///   ...
     ///  }
     ///
     ///  ...
     /// 
     public class Impersonator : IDisposable
     {
      private WindowsImpersonationContext _wic;
    
      /// 
      /// Begins impersonation with the given credentials, Logon type and Logon provider.
      /// 
      ///
    Name of the user.
      ///
    Name of the domain.
      ///
    The password. 
      ///
    Type of the logon.
      ///
    The logon provider. 
      public Impersonator(string userName, string domainName, string password, LogonType logonType, LogonProvider logonProvider)
      {
       Impersonate(userName, domainName, password, logonType, logonProvider);
      }
    
      /// 
      /// Begins impersonation with the given credentials.
      /// 
      ///
    Name of the user.
      ///
    Name of the domain.
      ///
    The password. 
      public Impersonator(string userName, string domainName, string password)
      {
       Impersonate(userName, domainName, password, LogonType.LOGON32_LOGON_INTERACTIVE, LogonProvider.LOGON32_PROVIDER_DEFAULT);
      }
    
      /// 
      /// Initializes a new instance of the  class.
      /// 
      public Impersonator()
      {}
    
      /// 
      /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
      /// 
      public void Dispose()
      {
       UndoImpersonation();
      }
    
      /// 
      /// Impersonates the specified user account.
      /// 
      ///
    Name of the user.
      ///
    Name of the domain.
      ///
    The password. 
      public void Impersonate(string userName, string domainName, string password)
      {
       Impersonate(userName, domainName, password, LogonType.LOGON32_LOGON_INTERACTIVE, LogonProvider.LOGON32_PROVIDER_DEFAULT);
      }
    
      /// 
      /// Impersonates the specified user account.
      /// 
      ///
    Name of the user.
      ///
    Name of the domain.
      ///
    The password. 
      ///
    Type of the logon.
      ///
    The logon provider. 
      public void Impersonate(string userName, string domainName, string password, LogonType logonType, LogonProvider logonProvider)
      {
       UndoImpersonation();
    
       IntPtr logonToken = IntPtr.Zero;
       IntPtr logonTokenDuplicate = IntPtr.Zero;
       try
       {
        // revert to the application pool identity, saving the identity of the current requestor
        _wic = WindowsIdentity.Impersonate(IntPtr.Zero);
    
        // do logon & impersonate
        if (Win32NativeMethods.LogonUser(userName,
            domainName,
            password,
            (int)logonType,
            (int)logonProvider,
            ref logonToken) != 0)
        {
         if (Win32NativeMethods.DuplicateToken(logonToken, (int)ImpersonationLevel.SecurityImpersonation, ref logonTokenDuplicate) != 0)
         {
          var wi = new WindowsIdentity(logonTokenDuplicate);
          wi.Impersonate(); // discard the returned identity context (which is the context of the application pool)
         }
         else
          throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        else
         throw new Win32Exception(Marshal.GetLastWin32Error());
       }
       finally
       {
        if (logonToken != IntPtr.Zero)
         Win32NativeMethods.CloseHandle(logonToken);
    
        if (logonTokenDuplicate != IntPtr.Zero)
         Win32NativeMethods.CloseHandle(logonTokenDuplicate);
       }
      }
    
      /// 
      /// Stops impersonation.
      /// 
      private void UndoImpersonation()
      {
       // restore saved requestor identity
       if (_wic != null)
        _wic.Undo();
       _wic = null;
      }
     }
    }
    

提交回复
热议问题