2011-05-11 153 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代替交互式登录。