我有一个启用了 Windows 身份验证(仅)的 IIS 网站(假设为 site.domain.com)。我的网站在其子网站上调用 HTTP rest API(假设为 site.domain.com/api)。它是不同的应用程序。当我以应用程序池标识的形式调用此 api 时,它工作正常。当我使用模拟时,我收到错误 401 Unauthorized。
IIS 服务器设置详细信息:
IIS 服务器由第三方负载平衡器进行负载平衡。IIS 管理器中的两个站点如下所示 图像
两个站点都只启用了 Windows 身份验证,并将 Negotiate 作为第一个提供商。两个站点都有不同的应用程序池。这些应用程序池具有相同的应用程序池标识(假设为 DOMAIN\apppool)。Spn 设置如下(您可以看到我尝试了所有方法):
PS C:\WINDOWS> setspn.exe -l DOMAIN\apppool
Registered ServicePrincipalNames for SOMECN:
HTTP/site/api
HTTP/site.domain.com/api
HTTP/site
HTTP/site.domain.com
我可以使用 Kerberos 与两个站点进行通信。两个站点均设置了 useAppPoolCredentials = True 和 useKernelMode = false。在 AD 应用程序池帐户中,标记了选项“信任此用户以委派任何服务(仅限 Kerberos)”
错误:
使用模拟的失败请求的 IIS 日志:
2017-10-04 14:40:57 192.168.81.101 GET /api/Test/Impersonate - 443 - 192.168.81.21 - - 401 2 5 1433
2017-10-04 14:40:57 192.168.81.101 GET /api/Test/Impersonate - 443 - 192.168.81.21 - - 401 1 2148074254 0
2017-10-04 14:40:57 192.168.81.101 GET /api/Test/Impersonate - 443 - 192.168.81.21 - - 401 1 5 15
使用应用程序池凭据(无需模拟)成功尝试的 IIS 日志:
2017-10-04 13:52:28 192.168.81.101 GET /api/Test/Impersonate - 443 - 192.168.81.21 - - 401 2 5 0
2017-10-04 13:52:28 192.168.81.101 GET /api/Test/Impersonate - 443 DOMAIN\apppool 192.168.81.21 - - 200 0 0 15
申请详情:
应用程序在我的开发机器上成功运行。问题只出现在生产中。在开发机器上,我使用我的主机名来访问该站点。
以下是我从 MVC 控制器调用 API 站点的方法:
[HttpGet]
public ViewResult ImpersonateTest()
{
System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext =
((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();
using (var client = new WebClient() { UseDefaultCredentials = true })
{
ViewBag.User = client.DownloadString(GlobalConfig.ApiPath + $"Test/Impersonate");
}
impersonationContext.Undo();
return View();
}
如果我删除前三行,则将使用应用程序池的凭据,并且一切按预期工作。但我想使用模拟 ofc。