2009-08-05 5 views
11

を使用しているとき、私はDirectoryInfoオブジェクトをインスタンス化したい場合は、共有にログオンするためUNCパスを持つC#の:どのようにDirectoryInfo

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

どのように私は、その共有へのアクセスに必要なユーザ名/パスワードを渡すことができますか?

おかげ

答えて

5

は、このアプローチを試してみてください:.NET 4で

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

/// <summary> 
/// Allows code to be executed under the security context of a specified user account. 
/// </summary> 
/// <remarks> 
/// 
/// 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] 
/// ... 
/// } 
/// 
/// ... 
/// </remarks> 
public class Impersonator : IDisposable 
{ 
    private WindowsImpersonationContext _wic; 

    /// <summary> 
    /// Begins impersonation with the given credentials, Logon type and Logon provider. 
    /// </summary> 
    /// 
<param name="userName">Name of the user.</param> 
    /// 
<param name="domainName">Name of the domain.</param> 
    /// 
<param name="password">The password. <see cref="System.String"/></param> 
    /// 
<param name="logonType">Type of the logon.</param> 
    /// 
<param name="logonProvider">The logon provider. <see cref="Mit.Sharepoint.WebParts.EventLogQuery.Network.LogonProvider"/></param> 
    public Impersonator(string userName, string domainName, string password, LogonType logonType, LogonProvider logonProvider) 
    { 
    Impersonate(userName, domainName, password, logonType, logonProvider); 
    } 

    /// <summary> 
    /// Begins impersonation with the given credentials. 
    /// </summary> 
    /// 
<param name="userName">Name of the user.</param> 
    /// 
<param name="domainName">Name of the domain.</param> 
    /// 
<param name="password">The password. <see cref="System.String"/></param> 
    public Impersonator(string userName, string domainName, string password) 
    { 
    Impersonate(userName, domainName, password, LogonType.LOGON32_LOGON_INTERACTIVE, LogonProvider.LOGON32_PROVIDER_DEFAULT); 
    } 

    /// <summary> 
    /// Initializes a new instance of the <see cref="Impersonator"/> class. 
    /// </summary> 
    public Impersonator() 
    {} 

    /// <summary> 
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 
    /// </summary> 
    public void Dispose() 
    { 
    UndoImpersonation(); 
    } 

    /// <summary> 
    /// Impersonates the specified user account. 
    /// </summary> 
    /// 
<param name="userName">Name of the user.</param> 
    /// 
<param name="domainName">Name of the domain.</param> 
    /// 
<param name="password">The password. <see cref="System.String"/></param> 
    public void Impersonate(string userName, string domainName, string password) 
    { 
    Impersonate(userName, domainName, password, LogonType.LOGON32_LOGON_INTERACTIVE, LogonProvider.LOGON32_PROVIDER_DEFAULT); 
    } 

    /// <summary> 
    /// Impersonates the specified user account. 
    /// </summary> 
    /// 
<param name="userName">Name of the user.</param> 
    /// 
<param name="domainName">Name of the domain.</param> 
    /// 
<param name="password">The password. <see cref="System.String"/></param> 
    /// 
<param name="logonType">Type of the logon.</param> 
    /// 
<param name="logonProvider">The logon provider. <see cref="Mit.Sharepoint.WebParts.EventLogQuery.Network.LogonProvider"/></param> 
    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); 
    } 
    } 

    /// <summary> 
    /// Stops impersonation. 
    /// </summary> 
    private void UndoImpersonation() 
    { 
    // restore saved requestor identity 
    if (_wic != null) 
    _wic.Undo(); 
    _wic = null; 
    } 
} 
} 
12

私はUNC経由なしWindowsサーバにログオンするために、このクラスは完璧に動作します。

using Microsoft.VisualBasic; 
using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Data; 
using System.Diagnostics; 
using System.Linq; 
using System.Web; 
using System.Runtime.InteropServices; 
using System.Security.Principal; 
using System.Web.Security; 


namespace toolsforimpersonations 
{ 
    public class Impersonator 
    { 
     #region "Consts" 

     public const int LOGON32_LOGON_INTERACTIVE = 2; 

     public const int LOGON32_PROVIDER_DEFAULT = 0; 
     #endregion 

     #region "External API" 
     [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", SetLastError = true)] 
     public static extern bool RevertToSelf(); 

     [DllImport("kernel32.dll", SetLastError = true)] 
     public static extern int CloseHandle(IntPtr hObject); 

     #endregion 

     #region "Methods" 

     //Public Sub PerformImpersonatedTask(ByVal username As String, ByVal domain As String, ByVal password As String, ByVal logonType As Integer, ByVal logonProvider As Integer, ByVal methodToPerform As Action) 
     public void PerformImpersonatedTask(string username, string domain, string password, int logonType, int logonProvider, Action methodToPerform) 
     { 
      IntPtr token = IntPtr.Zero; 
      if (RevertToSelf()) { 
       if (LogonUser(username, domain, password, logonType, logonProvider, ref token) != 0) { 
        dynamic identity = new WindowsIdentity(token); 
        dynamic impersonationContext = identity.Impersonate(); 
        if (impersonationContext != null) { 
         methodToPerform.Invoke(); 
         impersonationContext.Undo(); 
        } 
       // do logging 
       } else { 
       } 
      } 
      if (token != IntPtr.Zero) { 
       CloseHandle(token); 
      } 
     } 

     #endregion 
    } 

    public class UserImpersonation 
    { 
     const int LOGON32_LOGON_INTERACTIVE = 2; 
     const int LOGON32_LOGON_NETWORK = 3; 
     const int LOGON32_LOGON_BATCH = 4; 
     const int LOGON32_LOGON_SERVICE = 5; 
     const int LOGON32_LOGON_UNLOCK = 7; 
     const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8; 
     const int LOGON32_LOGON_NEW_CREDENTIALS = 9; 
     const int LOGON32_PROVIDER_DEFAULT = 0; 
     const int LOGON32_PROVIDER_WINNT35 = 1; 
     const int LOGON32_PROVIDER_WINNT40 = 2; 
     const int LOGON32_PROVIDER_WINNT50 = 3; 

     WindowsImpersonationContext impersonationContext; 
     [DllImport("advapi32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] 
     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, ExactSpelling = true)] 

     public static extern int DuplicateToken(IntPtr ExistingTokenHandle, int ImpersonationLevel, ref IntPtr DuplicateTokenHandle); 
     [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] 

     public static extern long RevertToSelf(); 
     [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] 
     public static extern long CloseHandle(IntPtr handle); 

     public bool impersonateUser(string userName, string domain, string password) 
     { 
      return impersonateValidUser(userName, domain, password); 
     } 

     public void undoimpersonateUser() 
     { 
      undoImpersonation(); 
     } 

     private bool impersonateValidUser(string userName, string domain, string password) 
     { 
      bool functionReturnValue = false; 

      WindowsIdentity tempWindowsIdentity = null; 
      IntPtr token = IntPtr.Zero; 
      IntPtr tokenDuplicate = IntPtr.Zero; 
      functionReturnValue = false; 

      //if (RevertToSelf()) { 
       if (LogonUserA(userName, domain, password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, ref token) != 0) { 
        if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) { 
         tempWindowsIdentity = new WindowsIdentity(tokenDuplicate); 
         impersonationContext = tempWindowsIdentity.Impersonate(); 
         if ((impersonationContext != null)) { 
          functionReturnValue = true; 
         } 
        } 
       } 
      //} 
      if (!tokenDuplicate.Equals(IntPtr.Zero)) { 
       CloseHandle(tokenDuplicate); 
      } 
      if (!token.Equals(IntPtr.Zero)) { 
       CloseHandle(token); 
      } 
      return functionReturnValue; 
     } 

     private void undoImpersonation() 
     { 
      impersonationContext.Undo(); 
     } 

    } 
} 

そして、これは、ディレクトリ内のすべてのファイルを一覧表示するこの小さな機能を使用する必要があなたのプログラムの開発

UserImpersonation impersonator = new UserImpersonation(); 
     impersonator.impersonateUser("username", "", "password"); //No Domain is required 

     List<FileInfo> OcDialerlfinfo = null; 
     OcDialerlfinfo = GetFileList("*", "\\\\10.11.11.122\\shared_folder"); 
     impersonator.undoimpersonateUser(); 

から、テストのために使用する方法である

public static List<FileInfo> GetFileList(string fileSearchPattern, string rootFolderPath) 
     { 
      DirectoryInfo rootDir = new DirectoryInfo(rootFolderPath); 

      List<DirectoryInfo> dirList = new List<DirectoryInfo>(rootDir.GetDirectories("*", SearchOption.AllDirectories)); 
      dirList.Add(rootDir); 

      List<FileInfo> fileList = new List<FileInfo>(); 

      foreach (DirectoryInfo dir in dirList) 
      { 
       fileList.AddRange(dir.GetFiles(fileSearchPattern, SearchOption.TopDirectoryOnly)); 
      } 

      return fileList; 
     } 
+0

これは[このMicrosoftのサポート記事](https://support.microsoft.com/en-us/kb/306158#bookmark-4)(ASP.NETの偽装については、よく)。サンプルコードは、一般的な使用に役立ちました。 – brichins