【发布时间】:2019-02-13 21:49:56
【问题描述】:
我有一个 WebApi 应用程序需要访问不同机器上的网络共享并打开 Crystal Reports 文件。
我正在使用LogonUser 和WindowsIdentity.Impersonate 使用此代码模拟有权访问网络共享的用户(不完整):
SafeTokenHandle safeTokenHandle;
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_LOGON_INTERACTIVE = 2;
bool returnValue = LogonUser(userName, domainName, userPassword, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out safeTokenHandle);
if (returnValue == false)
{
int ret = Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(ret);
}
using (safeTokenHandle)
using (var newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle()))
using (var impersonatedUser = newId.Impersonate())
{
actionToExecute();
}
例如,在使用托管代码 (System.IO) 列出文件夹或删除文件时,此功能可以正常工作。但是我需要打开 Crystal Reports 文件(我有最新版本),这样做时出现异常:
访问被拒绝
我假设 CR 正在尝试在应用程序池用户的上下文中加载文件。
如果我将应用程序池用户更改为在网络共享上有足够权限的域用户,我可能会得到这个工作。但我想避免这种解决方案。
将新的WindowsIdentity.RunImpersonated 用于.NET4.6 帮助还是会产生相同的结果。如果是,有没有办法让 CR 在提供的用户上下文中运行,而不是在应用程序池/AppDomain 用户中运行?
更新
通过将LogonUser 参数更改为LOGON32_LOGON_NEW_CREDENTIALS 和LOGON32_PROVIDER_WINNT50,我取得了部分成功。然后我测试了以下内容:
从 VS2017 本地启动项目(以便 WebApi 项目在本地 IIS Express 上下文中运行)并使用我机器上的客户端应用程序访问网络资源。这次测试很成功。
在单独的计算机上发布了 IIS 上的 WebApi 项目。在我的机器上启动客户端(ClickOnce)项目并访问相同的网络资源。此测试失败。
与(2)相同,但客户端发布并安装在另一台机器上,并使用终端服务器访问它。此测试失败。
为什么第一个测试成功但测试 2 和 3 失败?如果提供的登录参数并不总是有效,那么正确的登录参数应该是什么?
【问题讨论】:
-
如果您可以使用远程文件,那么听起来模拟很有效。但是“打开 Crystal Reports 文件”是什么意思,与在共享上打开文件有什么不同吗?也许水晶报表不支持这个。
-
您是否尝试过将共享文件夹映射为驱动器?
-
@SimonMourier 我的意思是将 .rpt 文件加载到文档中,设置参数并打印报告。
-
与从共享中打开它有何不同?
标签: c# asp.net-web-api crystal-reports asp.net-web-api2