【问题标题】:Reading remote file using ASP.NET impersonation使用 ASP.NET 模拟读取远程文件
【发布时间】: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

【问题讨论】:

    标签: c# asp.net


    【解决方案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 资源管理器访问该文件:如果您无法通过这种方式访问​​该文件,那么您的应用程序也不能.我经常发现我提供的部分信息不正确,例如密码或文件共享信息。
    • 非常感谢。脱帽致敬!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-19
    • 2013-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-13
    • 1970-01-01
    相关资源
    最近更新 更多