使用集成管道模式模拟域用户身份

23
在本地Intranet环境中,如果我们想要模拟Windows域用户并使用他们的身份验证,那么我们是否注定要在应用程序池中使用“经典”管道模式,或者有没有一种新的声明性方法来“以其身份”运行(可以这么说)?
我的目标是在我的Intranet上为本地Web应用程序使用Windows身份验证,以便用户可以在其活动目录帐户(原则)下进行身份验证和运行应用程序。每次我尝试这样做时(当然使用NetworkService标识),都会出现以下错误:

screenshot of error message

2个回答

27
我编写了一个小应用程序,用于显示当前用户的网络用户名,从多个不同的地方获取信息,例如 Page.User.Identity.Name 。我还使用了几种不同的方法来查询Active Directory以获取有关域用户的信息。所有这些都是为了验证以下内容。
我发现两种主要模式可用于使用Windows身份验证运行您的应用程序,在我的研究中主要用于Intranet环境。以下是配置的最低必要要素:
经典模式
- AppPool- 管道设置为Classic模式。 - AppPool- 标识设置为Network Service。 - 身份验证- 禁用:匿名身份验证 - 身份验证- 启用:ASP.NET模拟 - 身份验证- 启用:Windows身份验证 - 提供者- 禁用:Kerberos - 高级设置- 内核模式:任一
集成模式
  • AppPool - 托管管道设置为集成模式。
  • AppPool - 身份设置为 Network Service。
  • 身份验证 - 禁用:匿名身份验证
  • 身份验证 - 禁用:ASP.NET 模拟
  • 身份验证 - 启用:Windows 身份验证
  • 提供程序 - 启用:Kerberos
  • 高级设置 - 内核模式:禁用

现在关键的问题来了!

如果您想使用集成模式(这是理想的,因为它可以产生更多功能和更好的集成),则需要启用委派。以下是一些必读文章,以了解Delegation的基础知识,以及Dynamic SPN Registration的扩展。由于这涉及到更多的Kerberos和安全考虑,可能更容易坚持经典模式,在那里您只需启用模拟并称之为一天;或者欺骗并禁用validateIntegratedModeConfiguration


我刚在Visual Studio 2017中创建了一个新的MVC应用程序,并在设置向导中将身份验证设置为Windows身份验证(还选择了.net框架4.6.1),然后运行该应用程序,它自动识别了Windows用户。查看web.config文件,它根本没有identity/impersonate行。它只有<authentication mode="Windows" /> <authorization> <deny users="?" /> </authorization>所以我想知道为什么你要付出这么多努力,或者这是否已经在我的环境中配置好了,与.net无关? - tone
@tone 当您在生产服务器上运行应用程序时,与在本地计算机上使用IIS Express不同。您的本地计算机不会有委派凭据的问题。至少我所见过的是这样。 - Junior
@Chiramisu,使用您上面提到的经典设置使我能够获得正确的用户名,但我无法将用户名/密码委派给另一个服务/SDK。关于集成模式,是否每个使用我的应用程序的用户都需要启用Kerberos,还是只有运行PoolApp的用户需要?当我改变一切以匹配集成设置时,我无法再登录应用程序。它一直提示我提供我的用户名/密码。有什么想法吗? - Junior
@MikeA 确保在您的Windows身份验证>提供程序中,Kerberos排名第一。除此之外,很抱歉我不能提供更多帮助。 - Chiramisu
@Chiramisu 请不要撤销那些改善帖子格式的编辑,包括去除噪音和修正拼写错误等。 - TylerH
显示剩余2条评论

13

不,但“Integrated”管道需要你手动模拟Windows身份验证用户。至少在IIS8.5中是这样。

为什么?经典模拟会破坏.NET的异步功能。具体来说,在多个用户同时使用一个线程时,很难管理线程的WindowsIdentity。

如何实现?使用WindowsImpersonationContext 例如:

// Start with identity assigned by IIS Application Pool
var current = System.Security.Principal.WindowsIdentity.GetCurrent();

// Enable Windows Authentication in ASP.NET *and* IIS, which ensures 
// User.Identity is a WindowsIdentity
WindowsIdentity clientId = (WindowsIdentity)User.Identity;

// When 'using' block ends, the thread reverts back to previous Windows identity,
// because under the hood WindowsImpersonationContext.Undo() is called by Dispose()
using (WindowsImpersonationContext wic = clientId.Impersonate())
{
    // WindowsIdentity will have changed to match clientId
    current = System.Security.Principal.WindowsIdentity.GetCurrent();
}
// Back to the original identity
current = System.Security.Principal.WindowsIdentity.GetCurrent();

有问题吗?有时候你需要使用委派而不是模拟身份。


User类(例如User.Identity)来自哪里? - Coxy
这是MVC Controller类中的一个属性,因此您可以在控制器的操作中访问它,并将其传递到需要的位置。 - Corrodias

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接