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

时间:2014-01-04 01:59:01

标签: c# asp.net

我想阅读存储在远程服务器上的pdf。我收到了一个具有读访问权限的用户名/密码。

我正在使用此网址https://support.microsoft.com/kb/306158

中提供的ASP.NET模拟

我将所有内容记录到logFile只是为了帮助调试。

 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 个答案:

答案 0 :(得分: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,这也可能是您遇到的问题的一部分。