2011-05-11 106 views
1

我一直在C#(​​.net4)中的項目工作。項目幾乎允許人們將文件從本地機器上傳到網絡共享。將文件移動到網絡共享(通過模擬)C#

網絡共享是安全的。它只能由在活動目錄中創建的稱爲「代理」的用戶訪問。

我做了一些研究,我發現這個類,我用於冒充。

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

namespace Datacom.CorporateSys.Utilities 
{ 
    public class ImpersonateUser 
    { 
     [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); 

     WindowsImpersonationContext impersonationContext; 

     public const int LOGON32_LOGON_INTERACTIVE = 2; 
     public const int LOGON32_PROVIDER_DEFAULT = 0; 
     private string p; 
     private string p_2; 
     private string p_3; 


     private String UserName 
     { 
      set; 
      get; 
     } 

     private String Domain 
     { 
      set; 
      get; 
     } 

     private String Password 
     { 
      set; 
      get; 
     } 

     /// <summary> 
     /// Impersonates the user. 
     /// </summary> 
     /// <param name="userName">Name of the user.</param> 
     /// <param name="domain">The domain.</param> 
     /// <param name="password">The password.</param> 
     public ImpersonateUser(string userName, string domain, string password) 
     { 
      UserName = userName; 
      Domain = domain; 
      Password = password; 
     } 

     /// <summary> 
     /// Impersonates the valid user. 
     /// </summary> 
     /// <returns></returns> 
     public bool impersonateValidUser() 
     { 
      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; 
     } 

     /// <summary> 
     /// Undoes the impersonation. 
     /// </summary> 
     public void undoImpersonation() 
     { 
      impersonationContext.Undo(); 
     } 
    } 
} 

注意:從內存中我覺得我發現這是作爲msdn上的一個例子。

這是我嘗試從本地路徑文件移動到網絡

if (imp.impersonateValidUser()) 
          { 
           System.IO.File.Copy(local_file, server_file, true); 
           imp.undoImpersonation(); 
          } 
          else 
          { 
           throw new Exception("Unable to impersonate for uploading file."); 
          } 

和它的作品!我從來沒有模仿的問題 - 異常不會被拋出。它工作正常,並將文件上傳到服務器。但是,當我開始測試更多時,我發現如果代理用戶未登錄到服務器(通常我打開RDS登錄並退出 - 無需註銷)。

我得到不同的例外 - 找不到網絡路徑例外,它只有當我剛剛重新啓動服務器和「代理」未登錄時

我首先想到的是,有一些錯誤。模擬類,但它在模擬工作時模擬罰款(即文件擁有代理用戶的所有權)。然後我想可能是「代理」需要登錄,所以操作系統可以使用其權限實際訪問\服務器\上傳

我現在非常失落,不知道如何解決它。 請注意:我無法控制服務器。服務器是win2k8的桌面體驗安裝(否則我無法訪問任何網絡位置)。

謝謝!

+0

我已經做了一些調查。給我的網絡路徑實際上是通過WebDAV訪問的,因此我建議我們在我們的WinServer 2k8上安裝桌面體驗。 此示例適用於正常的「網絡」共享。但是,在通過WebDAV重定向器(桌面體驗)模擬webDAV時失敗。 http://learn.iis.net/page.aspx/386/using-the-webdav-redirector/ – Luke 2011-05-15 19:57:11

回答

1

授予代理帳戶訪問權限「作爲批處理作業登錄」並使用`LOGON32_LOGON_BATCH代替交互式登錄。