2013-06-20 34 views
2

我需要能夠在非域環境中嘗試讀取和寫入遠程計算機上的文件時以編程方式進行身份驗證。C#編程遠程文件夾/文件身份驗證在非域Windows環境中

當您在類似於\\ targetComputer \ C $ \ targetFolder或\\ targetComputer \ admin $的Windows RUN提示符下鍵入命令時,其中targetComputer不在域上,您將被提示輸入用戶名和密碼。一旦你輸入用戶名和密碼,你就可以完全訪問遠程文件夾。

如何在C#中以編程方式完成此身份驗證?

我試過..

--Impersonation,但它似乎只在域環境中工作。

--CMDKEY.exe,但它似乎也只適用於域環境。

必須有一種方法可以做到這一點,但我已經搜索到了高和低,沒有運氣到目前爲止。也許我只是在尋找錯誤的東西?我確信我不是第一個有這個問題的人。任何幫助將不勝感激。

謝謝!

編輯:

我想我只是發現了一個不同的,所以張貼的回答我的問題:Accessing a Shared File (UNC) From a Remote, Non-Trusted Domain With Credentials

我將與工作現在,看看那裏得到我。

謝謝!

+0

我想我只是發現了一個不同的,所以張貼的回答我的問題:訪問共享文件(UNC)從遠程,憑證不受信任的域名 我現在就要處理這個問題,看看它到底在哪裏。 謝謝! –

回答

9

模仿與對等/局域網絡一起工作。我在默認的「工作組」上使用了一些機器的典型家庭網絡,如果我記得在安裝時使用了某些機器,那麼我的系統上有一些機器。

這是我從我的IIS服務器的應用程序使用它來訪問我的其他計算機上的文件的代碼(而無需對涉及兩臺機器相同的用戶名和密碼,從某處複製和修改我的使用):

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Runtime.InteropServices; 
using System.Security.Principal; 
using System.ComponentModel; 

/// <summary> 
/// Class to impersonate another user. Requires user, pass and domain/computername 
/// All code run after impersonationuser has been run will run as this user. 
/// Remember to Dispose() afterwards. 
/// </summary> 
public class ImpersonateUser:IDisposable { 

    private WindowsImpersonationContext LastContext = null; 
    private IntPtr LastUserHandle = IntPtr.Zero; 

    #region User Impersonation api 
    [DllImport("advapi32.dll", SetLastError = true)] 
    public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken); 

    [DllImport("advapi32.dll", SetLastError = true)] 
    public static extern bool ImpersonateLoggedOnUser(int Token); 

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    public static extern bool DuplicateToken(IntPtr token, int impersonationLevel, ref IntPtr duplication); 

    [DllImport("kernel32.dll")] 
    public static extern Boolean CloseHandle(IntPtr hObject); 

    public const int LOGON32_PROVIDER_DEFAULT = 0; 
    public const int LOGON32_PROVIDER_WINNT35 = 1; 
    public const int LOGON32_LOGON_INTERACTIVE = 2; 
    public const int LOGON32_LOGON_NETWORK = 3; 
    public const int LOGON32_LOGON_BATCH = 4; 
    public const int LOGON32_LOGON_SERVICE = 5; 
    public const int LOGON32_LOGON_UNLOCK = 7; 
    public const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8;// Win2K or higher 
    public const int LOGON32_LOGON_NEW_CREDENTIALS = 9;// Win2K or higher 
    #endregion 

    public ImpersonateUser(string username, string domainOrComputerName, string password, int nm = LOGON32_LOGON_NETWORK) { 

     IntPtr userToken = IntPtr.Zero; 
     IntPtr userTokenDuplication = IntPtr.Zero; 

     bool loggedOn = false; 

     if (domainOrComputerName == null) domainOrComputerName = Environment.UserDomainName; 

     if (domainOrComputerName.ToLower() == "nt authority") { 
      loggedOn = LogonUser(username, domainOrComputerName, password, LOGON32_LOGON_SERVICE, LOGON32_PROVIDER_DEFAULT, out userToken); 
     } else { 
      loggedOn = LogonUser(username, domainOrComputerName, password, nm, LOGON32_PROVIDER_DEFAULT, out userToken); 
     } 

     WindowsImpersonationContext _impersonationContext = null; 
     if (loggedOn) { 
      try { 
       // Create a duplication of the usertoken, this is a solution 
       // for the known bug that is published under KB article Q319615. 
       if (DuplicateToken(userToken, 2, ref userTokenDuplication)) { 
        // Create windows identity from the token and impersonate the user. 
        WindowsIdentity identity = new WindowsIdentity(userTokenDuplication); 
        _impersonationContext = identity.Impersonate(); 
       } else { 
        // Token duplication failed! 
        // Use the default ctor overload 
        // that will use Mashal.GetLastWin32Error(); 
        // to create the exceptions details. 
        throw new Win32Exception(); 
       } 
      } finally { 
       // Close usertoken handle duplication when created. 
       if (!userTokenDuplication.Equals(IntPtr.Zero)) { 
        // Closes the handle of the user. 
        CloseHandle(userTokenDuplication); 
        userTokenDuplication = IntPtr.Zero; 
       } 

       // Close usertoken handle when created. 
       if (!userToken.Equals(IntPtr.Zero)) { 
        // Closes the handle of the user. 
        CloseHandle(userToken); 
        userToken = IntPtr.Zero; 
       } 
      } 
     } else { 
      // Logon failed! 
      // Use the default ctor overload that 
      // will use Mashal.GetLastWin32Error(); 
      // to create the exceptions details. 
      throw new Win32Exception(); 
     } 

     if (LastContext == null) LastContext = _impersonationContext; 
    } 

    public void Dispose() { 
     LastContext.Undo(); 
     LastContext.Dispose(); 
    } 
} 

我發現了特定的代碼位的嘗試後的工作是這樣的:

using (var impersonation = new ImpersonateUser("OtherMachineUser", "OtherMachineName", "Password", LOGON32_LOGON_NEW_CREDENTIALS)) 
    { 
     var files = System.IO.Directory.GetFiles("\\OtherMachineName\fileshare"); 
    } 
+0

我能夠使用下面的代碼來解決我的問題:http://stackoverflow.com/questions/659013/accessing-a-shared-file-unc-from-a-remote-non-trusted-domain-with-憑證?RQ = 1。然而,我很好奇後來測試你的代碼(我想我實際上可能有......感覺就像我在發佈這個問題之前在SO上看到的那樣),看看它與我原來的模擬代碼相比如何。你的代碼的第一眼就是它看起來就像我以前使用的代碼,只在域環境中取得成功。稍後我會更仔細地研究它。謝謝。 –

+2

關鍵是:LOGON32_LOGON_NEW_CREDENTIALS。我嘗試了所有不同的選擇,並且LOGON32_LOGON_NEW_CREDENTIALS是有效的。其餘代碼是通用的。 – Wolf5

+0

非常有趣。我一定會嘗試一下並回報。謝謝! –