Eu tenho o site do IIS com o windows auth (somente) habilitado (digamos site.domain.com). Meu site chama HTTP rest API em seu subsite (digamos site.domain.com/api). É uma aplicação diferente. Funciona bem, quando eu chamo esta API como identidade do pool de aplicativos. Quando eu uso a representação, recebo o erro 401 não autorizado.
Detalhes da configuração do servidor IIS:
Os servidores IIS são carregados pelo balanceador de carga de terceiros. Dois sites no gerenciador do IIS parecem imagem
Ambos os sites têm apenas o windows auth ativado e negociam como o primeiro provedor. Ambos os sites têm um pool de aplicativos diferente. Esses pools de aplicativos têm a mesma identidade do pool de aplicativos (digamos DOMAIN \ apppool). A configuração do Spn é (você pode ver que tentei tudo):
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
Eu posso me comunicar com os dois sites usando o Kerberos. useAppPoolCredentials = True e useKernelMode = false está configurado para ambos os sites. Na conta do pool de aplicativos do AD, foi marcada a opção "Confiar este usuário para delegação a qualquer serviço (somente Kerberos)"
Erro:
Registro do IIS para solicitação com falha usando Representação:
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
Registro do IIS para tentativas bem-sucedidas usando credenciais do pool de aplicativos (sem representação):
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
Detalhes da aplicação:
O aplicativo é executado com sucesso na minha máquina de desenvolvimento. O problema está apenas na produção. Na máquina de desenvolvimento, eu uso meu nome de host para acessar o site.
Aqui está como eu chamo o site da API do meu controlador MVC:
[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();
}
Se eu remover as três primeiras linhas, as credenciais do pool de aplicativos serão usadas e tudo funcionará como esperado. Mas eu quero usar a representação de c.