【发布时间】:2016-03-15 07:12:33
【问题描述】:
当前设置是这样的,服务器 A 托管电子服务,服务器 B 是本地和内部服务器。我想在服务器A的浏览器中显示pdf文件,服务器A将从服务器B获取。
现在服务器 A 与服务器 B 不在同一个域或组中。
当我访问服务器 A 并在文件浏览器中键入路径“\\serverB\folder\file.pdf”时,我可以打开它并查看它。
当我使用 Visual Studio 进行调试时,以下代码也可以正常工作并查看文件:
Response.ClearContent();
Response.ClearHeaders();
Response.AddHeader("Content-Disposition", "inline;filename=" + fpath);
Response.ContentType = "application/pdf";
Response.WriteFile(fpath);
Response.Flush();
Response.Clear();
其中 fpath 是文件的路径。
但是,当我尝试从浏览器访问它时,我得到了 Access is denied 错误。
我尝试通过以下代码进行模拟:
public class Impersonation
{
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
// Test harness.
// If you incorporate this code into a DLL, be sure to demand FullTrust.
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public WindowsImpersonationContext ImpersonateUser(string domain , string user, string pass)
{
SafeTokenHandle safeTokenHandle;
try
{
// Get the user token for the specified user, domain, and password using the
// unmanaged LogonUser method.
// The local machine name can be used for the domain name to impersonate a user on this machine.
//Console.Write("Enter the name of the domain on which to log on: ");
// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(user, domain, pass,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
out safeTokenHandle);
if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(ret);
}
using (safeTokenHandle)
{
// Use the token handle returned by LogonUser.
using (WindowsIdentity newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle()))
{
using (WindowsImpersonationContext impersonatedUser = newId.Impersonate())
{
return newId.Impersonate();
}
}
// Releasing the context object stops the impersonation
}
}
catch (Exception ex)
{
}
return null;
}
}
public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private SafeTokenHandle()
: base(true)
{
}
[DllImport("kernel32.dll")]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
protected override bool ReleaseHandle()
{
return CloseHandle(handle);
}
}
并像这样使用它:
Impersonation impersonate = new Impersonation();
using (System.Security.Principal.WindowsImpersonationContext impUser = impersonate.ImpersonateUser("Domain", "User", "Password"))
{
bool endResponse = false;
try
{
byte[] b = null;
using (System.IO.FileStream fs = System.IO.File.OpenRead(fpath))
{
b = new byte[fs.Length];
fs.Read(b, 0, b.Length);
}
Response.AddHeader("Content-Type", "application/pdf");
Response.AddHeader("Content-Disposition", "attachment;filename=Report.pdf");
Response.OutputStream.Write(b, 0, b.Length);
Response.Flush();
Response.Close();
endResponse = true;
}
catch (Exception ex)
{
throw;
}
finally
{
}
if (endResponse)
Response.End();
}
它不会检索所需的用户,而是检索服务器 A 的用户,但是在使用 Visual Studio 进行调试时它确实可以工作并且不会引发错误,但是从 Web 浏览器访问它时仍然会引发错误。
【问题讨论】: