【问题标题】:IIS Impersonation not working when app pool runs with domain account当应用程序池使用域帐户运行时,IIS 模拟不起作用
【发布时间】:2020-01-09 14:54:13
【问题描述】:

我有一个在 Windows Intranet 环境中运行的 ASP.net 应用程序。我需要以当前登录用户的身份执行某些数据库更新。

IIS/服务器信息:

  • IIS 版本 10
  • Windows 服务器 2019
  • ASP.net 网络表单应用程序
  • .NET 4.7
  • Windows 身份验证 已启用
  • 模拟匿名身份验证已禁用
  • 应用程序池使用集成管道
  • 应用程序池使用 域服务帐户 作为其身份运行,该身份有权根据需要访问其他资源。

其他细节:

  • 我的所有数据库连接字符串都设置为 integrated security=true
  • 在活动目录中,已配置 Web 服务器和 SQL 服务器之间的约束委派,允许 MSSQLSvc : 1433MSSQLSvc(无端口)
  • 域服务帐户是网络服务器上本地管理员组的成员(仅用于测试目的)

当我以当前登录用户的身份执行需要完成的数据库更新时,我以这种方式模拟它们:

 var windowsIdentity = User.Identity as WindowsIdentity;
 WindowsIdentity.RunImpersonated(windowsIdentity.AccessToken, () =>
 {
     // perform database update
 });

这会引发异常 - System.Data.SqlClient.SqlException: Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'

如果我将应用程序池标识更改为使用 AppPoolIdentity(默认应用程序池标识),则模拟工作正常。

为什么这种模拟适用于 AppPoolIdentity,但不适用于我的域服务帐户

【问题讨论】:

    标签: c# asp.net iis impersonation kerberos-delegation


    【解决方案1】:

    我以前也遇到过类似的问题,我看到你正在使用 Kerberos,一旦你得到它就可以了!

    在与您类似的情况下,对我有用的方法是打开 IIS,转到您的站点,单击配置编辑器图标。在顶部两个标题中,首先单击“发件人”下拉菜单并选择“ApplicationHost.config”,然后在“发件人”左侧的“部分”标题中,单击下拉菜单,然后展开文件夹:

    system.WebServer->security->authentication->windowsAuthentication,

    根据您的情况,您可以从此处的选项中选择“useAppPoolCredentials”并将其设置为 TRUE。

    当您将“useAppPoolCredentials”设置为 true 时,您告诉 IIS 它需要使用其应用程序池标识,您将其定义为域服务帐户来解密返回的授权票证。用户配置文件通常没有执行此操作的规定。

    如果这不起作用,要尝试的另一件事是在应用程序池的高级设置中切换“加载用户配置文件”设置,我不确定 True 或 False 是否会解决您的问题,但似乎帮助解决之前的类似问题。我会先尝试上述方法,如果不起作用,请尝试以下操作:

    我没有看到任何关于 SPN 的内容,你在使用这些吗?将域帐户作为应用程序池 ID 运行时可能需要它们。下面的文章记录了该步骤以及其他许多使其工作的步骤:

    https://techcommunity.microsoft.com/t5/iis-support-blog/setting-up-kerberos-authentication-for-a-website-in-iis/ba-p/324644

    此外,这里有一些文章极大地帮助了我在工作中完成这一切。

    https://docs.microsoft.com/en-us/archive/blogs/chiranth/setting-up-kerberos-authentication-for-a-website-in-iis

    https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-2000-server/cc961723(v=technet.10)?redirectedfrom=MSDN

    希望这会有所帮助。

    更新:对于仍在寻求解决此问题的帮助的人,我们为我们的系统找到了一种不需要模拟/委托的解决方法:

    相反,我们创建了另一个 API 端点,一个“中点”,它接收来自初始端点的请求,无需模拟。在这种情况下,我们能够创建一个中间系统帐户作为中间点的应用程序池 ID 运行,然后该 ID 用于查询数据库,这是系统帐户的唯一访问权限,这足以保证安全团队可以接受。我们意识到,根据我们的协议,当我们使用特殊特权系统帐户时,不需要记录拨打电话的个人。

    【讨论】:

    • 非常感谢您的回复。此时,我尝试将 useAppPoolCredentials 设置为 true - 这会导致在浏览器中提示输入凭据,然后是 http 401。此外,更改 LoadUserProfile 没有效果:( 至于 SPN,我对域进行了以下设置服务帐户:- sql server-MSSqlSvc:1433 - sql server-MSSqlSvc(无端口)我正在查看您现在引用的文章,看看我能发现什么 :)
    • 所以,在所有事情之后,最终的工作是将 Web 服务器和 SQL 服务器之间的委派从**“信任这台计算机以进行特定服务的委派”**(约束委派)切换到 '信任此计算机以委托给任何服务(仅限 kerberos)'。我确信我可以添加一项明确的服务以使其正常工作,而不是允许所有服务。知道那可能是什么吗?
    • 据我所知,您将委托给 IIS 为该页面的请求生成的任何日志名称。这将识别特定的服务名称。在 inetpub 文件夹中,找到日志,找到与您的请求匹配的日志。可能有更简单的方法可以找到它,但我不确定。就我而言,它是 W3CSVC3,因为在这个特定的服务器上有 3 个不同的 api 端点。
    • 不 - 仍在以不受约束的委托运行:(
    • 该死,很遗憾听到这个消息。最后,我们实际上最终找到了一个不需要模拟的解决方案,因为当 IIS 服务器上运行的 Web 服务超过 1 个时,我们在约束委派时也遇到了麻烦。相反,我们创建了另一个 API 端点,即“中点”,并从初始端点接收请求,而不进行模拟。在这种情况下,我们能够创建一个中间系统帐户来作为中间点的应用程序池 ID 运行,然后该 ID 用于查询数据库,这足以让安全团队接受它。
    猜你喜欢
    • 1970-01-01
    • 2014-10-01
    • 1970-01-01
    • 2013-03-20
    • 2012-06-20
    • 1970-01-01
    • 2021-04-22
    • 1970-01-01
    相关资源
    最近更新 更多