【问题标题】:How to use impersonation to access a network resource from IIS?如何使用模拟从 IIS 访问网络资源?
【发布时间】:2019-02-13 21:49:56
【问题描述】:

我有一个 WebApi 应用程序需要访问不同机器上的网络共享并打开 Crystal Reports 文件。

我正在使用LogonUserWindowsIdentity.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_CREDENTIALSLOGON32_PROVIDER_WINNT50,我取得了部分成功。然后我测试了以下内容:

  1. 从 VS2017 本地启动项目(以便 WebApi 项目在本地 IIS Express 上下文中运行)并使用我机器上的客户端应用程序访问网络资源。这次测试很成功。

  2. 在单独的计算机上发布了 IIS 上的 WebApi 项目。在我的机器上启动客户端(ClickOnce)项目并访问相同的网络资源。此测试失败。

  3. 与(2)相同,但客户端发布并安装在另一台机器上,并使用终端服务器访问它。此测试失败。

为什么第一个测试成功但测试 2 和 3 失败?如果提供的登录参数并不总是有效,那么正确的登录参数应该是什么?

【问题讨论】:

  • 如果您可以使用远程文件,那么听起来模拟很有效。但是“打开 Crystal Reports 文件”是什么意思,与在共享上打开文件有什么不同吗?也许水晶报表不支持这个。
  • 您是否尝试过将共享文件夹映射为驱动器?
  • @SimonMourier 我的意思是将 .rpt 文件加载到文档中,设置参数并打印报告。
  • 与从共享中打开它有何不同?

标签: c# asp.net-web-api crystal-reports asp.net-web-api2


【解决方案1】:

问题在于 ReportDocument 没有 LoadImpersonate 之类的功能,因此,它总是会尝试使用应用程序池权限打开 .rpt 文件。

您需要的是委托,而不是模拟,如果您使用 Windows 身份验证和活动目录,您需要授权您的服务器和/或您的应用程序池帐户以进行委托...

https://support.microsoft.com/en-us/help/810572/how-to-configure-an-asp-net-application-for-a-delegation-scenario

这样app-pool账号会使用用户的权限来访问资源

如果这不可行,作为一种解决方法,您可以使用模拟将 .rpt 文件复制到您的应用程序池帐户的可访问位置,并在使用后将其删除...

【讨论】:

    【解决方案2】:
    猜你喜欢
    • 2023-03-11
    • 2010-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-09
    • 2012-02-20
    • 2015-09-08
    • 2011-10-15
    相关资源
    最近更新 更多