Depurar erros de autenticação do Windows
Ao usar a autenticação do Windows como um mecanismo de segurança, a Interface do Provedor de Suporte de Segurança (SSPI) lida com processos de segurança. Quando ocorrem erros de segurança na camada SSPI, eles são apresentados pelo Windows Communication Foundation (WCF). Este tópico fornece uma estrutura e um conjunto de perguntas para ajudar a diagnosticar os erros.
Para obter uma visão geral do protocolo Kerberos, consulte Kerberos Explained; para obter uma visão geral do SSPI, consulte SSPI.
Para autenticação do Windows, o WCF normalmente usa o SSP (Negotiate Security Support Provider), que executa a autenticação mútua Kerberos entre o cliente e o serviço. Se o protocolo Kerberos não estiver disponível, por padrão, o WCF retornará ao NT LAN Manager (NTLM). No entanto, você pode configurar o WCF para usar apenas o protocolo Kerberos (e para lançar uma exceção se Kerberos não estiver disponível). Você também pode configurar o WCF para usar formulários restritos do protocolo Kerberos.
Metodologia de depuração
O método básico é o seguinte:
Determine se você está usando a autenticação do Windows. Se você estiver usando qualquer outro esquema, este tópico não se aplica.
Se tiver certeza de que está usando a autenticação do Windows, determine se a configuração do WCF usa Kerberos direct ou Negotiate.
Depois de determinar se sua configuração está usando o protocolo Kerberos ou NTLM, você pode entender as mensagens de erro no contexto correto.
Disponibilidade do Protocolo Kerberos e NTLM
O SSP Kerberos requer um controlador de domínio para atuar como o Centro de Distribuição de Chaves Kerberos (KDC). O protocolo Kerberos está disponível somente quando o cliente e o serviço estão usando identidades de domínio. Em outras combinações de contas, o NTLM é usado, conforme resumido na tabela a seguir.
Os cabeçalhos da tabela mostram possíveis tipos de conta usados pelo servidor. A coluna da esquerda mostra os possíveis tipos de conta usados pelo cliente.
Utilizador Local | Sistema Local | Usuário do Domínio | Máquina de domínio | |
---|---|---|---|---|
Utilizador Local | NTLM | NTLM | NTLM | NTLM |
Sistema Local | Anônimo NTLM | Anônimo NTLM | Anônimo NTLM | Anônimo NTLM |
Usuário do Domínio | NTLM | NTLM | Kerberos | Kerberos |
Máquina de domínio | NTLM | NTLM | Kerberos | Kerberos |
Especificamente, os quatro tipos de conta incluem:
Usuário local: perfil de usuário somente máquina. Por exemplo:
MachineName\Administrator
ouMachineName\ProfileName
.Sistema Local: A conta interna SYSTEM em uma máquina que não está associada a um domínio.
Usuário do domínio: uma conta de usuário em um domínio do Windows. Por exemplo:
DomainName\ProfileName
.Máquina de domínio: um processo com identidade de máquina em execução em uma máquina associada a um domínio do Windows. Por exemplo:
MachineName\Network Service
.
Nota
A credencial de serviço é capturada quando o Open método da ServiceHost classe é chamado. A credencial do cliente é lida sempre que o cliente envia uma mensagem.
Problemas comuns de autenticação do Windows
Esta seção discute alguns problemas comuns de autenticação do Windows e possíveis soluções.
Protocolo Kerberos
Problemas SPN/UPN com o protocolo Kerberos
Ao usar a autenticação do Windows e o protocolo Kerberos for usado ou negociado pela SSPI, a URL usada pelo ponto de extremidade do cliente deve incluir o nome de domínio totalmente qualificado do host do serviço dentro da URL do serviço. Isso pressupõe que a conta sob a qual o serviço está sendo executado tenha acesso à chave SPN (nome da entidade de serviço) da máquina (padrão) que é criada quando o computador é adicionado ao domínio do Ative Directory, o que geralmente é feito executando o serviço na conta do Serviço de Rede. Se o serviço não tiver acesso à chave SPN da máquina, você deverá fornecer o SPN correto ou o UPN (nome principal do usuário) da conta sob a qual o serviço está sendo executado na identidade do ponto de extremidade do cliente. Para obter mais informações sobre como o WCF funciona com SPN e UPN, consulte Identidade e autenticação do serviço.
Em cenários de balanceamento de carga, como Web farms ou Web gardens, uma prática comum é definir uma conta exclusiva para cada aplicativo, atribuir um SPN a essa conta e garantir que todos os serviços do aplicativo sejam executados nessa conta.
Para obter um SPN para a conta do serviço, você precisa ser um administrador de domínio do Ative Directory. Para obter mais informações, consulte Suplemento técnico Kerberos para Windows.
O Kerberos Protocol Direct requer que o serviço seja executado em uma conta de máquina de domínio
Isso ocorre quando a ClientCredentialType
propriedade é definida como Windows
e a NegotiateServiceCredential propriedade é definida como false
, conforme mostrado no código a seguir.
WSHttpBinding b = new WSHttpBinding();
// By default, the WSHttpBinding uses Windows authentication
// and Message mode.
b.Security.Message.NegotiateServiceCredential = false;
Dim b As New WSHttpBinding()
' By default, the WSHttpBinding uses Windows authentication
' and Message mode.
b.Security.Message.NegotiateServiceCredential = False
Para remediar, execute o serviço usando uma conta de Máquina de Domínio, como Serviço de Rede, em uma máquina associada a um domínio.
A delegação requer negociação de credenciais
Para usar o protocolo de autenticação Kerberos com delegação, você deve implementar o protocolo Kerberos com negociação de credenciais (às vezes chamado de Kerberos "multi-leg" ou "multi-step"). Se você implementar a autenticação Kerberos sem negociação de credenciais (às vezes chamado de Kerberos "one-shot" ou "single-leg"), uma exceção será lançada.
Para implementar Kerberos com negociação de credenciais, execute as seguintes etapas:
Implemente a delegação definindo AllowedImpersonationLevel como Delegation.
Exigir negociação SSPI:
Se você estiver usando associações padrão, defina a
NegotiateServiceCredential
propriedade comotrue
.Se você estiver usando associações personalizadas, defina o
AuthenticationMode
Security
atributo do elemento comoSspiNegotiated
.
Exija que a negociação SSPI use Kerberos não permitindo o uso de NTLM:
Faça isso no código, com a seguinte instrução:
ChannelFactory.Credentials.Windows.AllowNtlm = false
Ou você pode fazer isso no arquivo de configuração definindo o
allowNtlm
atributo comofalse
. Este atributo está contido nas janelas>.<
Protocolo NTLM
Negociar SSP retorna ao NTLM, mas o NTLM está desabilitado
A AllowNtlm propriedade é definida como , o false
que faz com que o Windows Communication Foundation (WCF) faça o melhor esforço para lançar uma exceção se NTLM for usado. Definir essa propriedade como false
não pode impedir que as credenciais NTLM sejam enviadas por fio.
A seguir mostra como desabilitar o fallback para NTLM.
CalculatorClient cc = new
CalculatorClient("WSHttpBinding_ICalculator");
cc.ClientCredentials.Windows.AllowNtlm = false;
Dim cc As New CalculatorClient("WSHttpBinding_ICalculator")
cc.ClientCredentials.Windows.AllowNtlm = False
Falha de logon NTLM
As credenciais do cliente não são válidas no serviço. Verifique se o nome de utilizador e a palavra-passe estão corretamente definidos e correspondem a uma conta conhecida do computador onde o serviço está a ser executado. NTLM usa as credenciais especificadas para fazer logon no computador do serviço. Embora as credenciais possam ser válidas no computador em que o cliente está sendo executado, esse logon falhará se as credenciais não forem válidas no computador do serviço.
Logon NTLM anônimo ocorre, mas logons anônimos são desabilitados por padrão
Ao criar um cliente, a AllowedImpersonationLevel propriedade é definida como Anonymous, conforme mostrado no exemplo a seguir, mas, por padrão, o servidor não permite logons anônimos. Isso ocorre porque o AllowAnonymousLogons valor padrão da propriedade da WindowsServiceCredential classe é false
.
O código de cliente a seguir tenta habilitar logons anônimos (observe que a propriedade padrão é Identification
).
CalculatorClient cc =
new CalculatorClient("WSHttpBinding_ICalculator");
cc.ClientCredentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Anonymous;
Dim cc As New CalculatorClient("WSHttpBinding_ICalculator")
cc.ClientCredentials.Windows.AllowedImpersonationLevel = _
System.Security.Principal.TokenImpersonationLevel.Anonymous
O código de serviço a seguir altera o padrão para habilitar logons anônimos pelo servidor.
Uri httpUri = new Uri("http://localhost:8000/");
ServiceHost sh = new ServiceHost(typeof(Calculator), httpUri);
sh.Credentials.WindowsAuthentication.AllowAnonymousLogons = true;
Dim httpUri As New Uri("http://localhost:8000/")
Dim sh As New ServiceHost(GetType(Calculator), httpUri)
sh.Credentials.WindowsAuthentication.AllowAnonymousLogons = True
Para obter mais informações sobre representação, consulte Delegação e representação.
Como alternativa, o cliente está sendo executado como um serviço do Windows, usando a conta interna SYSTEM.
Outros problemas
As credenciais do cliente não estão definidas corretamente
A autenticação do Windows usa a WindowsClientCredential instância retornada pela ClientCredentials propriedade da ClientBase<TChannel> classe, não o UserNamePasswordClientCredential. A seguir mostra um exemplo incorreto.
CalculatorClient cc = new
CalculatorClient("WSHttpBinding_ICalculator");
cc.ClientCredentials.UserName.UserName = GetUserName(); // wrong!
cc.ClientCredentials.UserName.Password = GetPassword(); // wrong!
Dim cc As New CalculatorClient("WSHttpBinding_ICalculator")
cc.ClientCredentials.UserName.UserName = GetUserName() ' wrong!
cc.ClientCredentials.UserName.Password = GetPassword() ' wrong!
A seguir mostra o exemplo correto.
CalculatorClient cc = new
CalculatorClient("WSHttpBinding_ICalculator");
// This code returns the WindowsClientCredential type.
cc.ClientCredentials.Windows.ClientCredential.UserName = GetUserName();
cc.ClientCredentials.Windows.ClientCredential.Password = GetPassword();
Dim cc As New CalculatorClient("WSHttpBinding_ICalculator")
' This code returns the WindowsClientCredential type.
cc.ClientCredentials.Windows.ClientCredential.UserName = GetUserName()
cc.ClientCredentials.Windows.ClientCredential.Password = GetPassword()
SSPI não está disponível
Os seguintes sistemas operativos não suportam a autenticação do Windows quando utilizados como servidor: Windows XP Home Edition, Windows XP Media Center Edition e Windows Vista Home editions.
Desenvolvendo e implantando com identidades diferentes
Se você desenvolver seu aplicativo em uma máquina e implantar em outra, e usar diferentes tipos de conta para autenticar em cada máquina, você pode enfrentar um comportamento diferente. Por exemplo, suponha que você desenvolva seu aplicativo em uma máquina Windows XP Pro usando o modo de SSPI Negotiated
autenticação. Se você usar uma conta de usuário local para autenticar, o protocolo NTLM será usado. Depois que o aplicativo é desenvolvido, você implanta o serviço em uma máquina Windows Server 2003 onde ele é executado em uma conta de domínio. Neste ponto, o cliente não poderá autenticar o serviço porque usará Kerberos e um controlador de domínio.