使用 ASP.NET 模拟读取远程文件

Posted

技术标签:

【中文标题】使用 ASP.NET 模拟读取远程文件【英文标题】:Reading remote file using ASP.NET impersonation 【发布时间】:2014-01-04 01:59:00 【问题描述】:

我想阅读存储在远程服务器上的 pdf。我已获得具有读取访问权限的用户名/密码。

我正在使用此 url https://support.microsoft.com/kb/306158 中给出的 ASP.NET 模拟

我将所有内容都记录到日志文件中只是为了帮助调试。

 StreamWriter sw = new StreamWriter(Server.MapPath("~/log/logFile.txt"), true);
 sw.WriteLine("Just before Impersonation");

 if(impersonateValidUser("username", "domain", "password"))
 
    try
     
          byte[] bytes = File.ReadAllBytes(documentName);
          sw.WriteLine("Bytes read!!");
          undoImpersonation();
     
    catch(Exception ex)
    
       sw.WriteLine(ex.Message + "\n" + ex.StackTrace);
       return;
 
 else
 
    sw.WriteLine("Impersonation Failed");
            return;
 

在我的日志文件中,我只看到“就在模拟之前”。 try 和 catch 块的消息都不会写入日志文件。令人惊讶的是,我没有看到模拟失败消息。

只是想知道是否有人以前有过这种行为的经验?访问远程机器上的文件是否有任何额外要求?我知道远程机器确实有 advapi32.dll 和 kernel32.dll

【问题讨论】:

【参考方案1】:

我们在使用 MSDN 示例时也遇到了问题,如果我没记错的话,这与句柄过早关闭有关。

我们最终以以下方式重写了它,这对我们来说非常有效:

    private void DoLogin()
    
        var token = LogonAsUser(userName, domain, password);
        if (!IntPtr.Equals(token, IntPtr.Zero))
        
            WindowsImpersonationContext impersonatedUser = null;
            try
            
                var newIdentity = new WindowsIdentity(token);

                impersonatedUser = newIdentity.Impersonate();

                // Do impersonated work here
            
            finally
            
                if (impersonatedUser != null)
                
                    impersonatedUser.Undo();
                
                LogonAsUserEnd(token);
            
        
    

    private IntPtr LogonAsUser(String userName, String domain, String password)
    
        IntPtr token = IntPtr.Zero;

        if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
        
            return token;
        
        else
        
            return IntPtr.Zero;
        
    

    private void LogonAsUserEnd(IntPtr token) 
        if (!IntPtr.Equals(token, IntPtr.Zero))
        
            CloseHandle(token);
        

    

另外一个说明:我们将 LogonUserA 定义为返回 bool,而不是 int,这也可能是您遇到的问题的一部分。

【讨论】:

感谢您的代码,它现在至少进入了捕获部分(仍然无法读取字节 - 访问被拒绝)。我提供的用户名具有读取权限,对奇怪的行为非常好奇 @bluepiranha:请记住,用户必须有权访问共享和文件。共享权限与文件权限是分开提供的,这经常会让人绊倒。在这种情况下,我总是做的是使用提供的凭据登录我正在测试的机器,然后尝试通过 Windows 资源管理器访问该文件:如果您无法通过这种方式访问​​该文件,那么您的应用程序也不能.我经常发现我提供的部分信息不正确,例如密码或文件共享信息。 非常感谢。脱帽致敬!

以上是关于使用 ASP.NET 模拟读取远程文件的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NE网站发布注意事项

跟我学ASP.NET MVC之十一:URL路由

asp.net 点击一下文件名或者一个下载按钮,将文件下载下来怎么做啊???

ASP.NET 核心标识。使用 ApplicationDbContext 和 UserManager。他们是不是共享上下文?

在 WPF、Silverlight 和 ASP.NET 之间共享一个公共 DAL

ASP.NET Web API 身份验证(Web + 移动)