Partilhar via


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:

  1. Determine se você está usando a autenticação do Windows. Se você estiver usando qualquer outro esquema, este tópico não se aplica.

  2. Se tiver certeza de que está usando a autenticação do Windows, determine se a configuração do WCF usa Kerberos direct ou Negotiate.

  3. 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:

  • Utilizador local: perfil de utilizador exclusivo para máquina. Por exemplo: MachineName\Administrator ou MachineName\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.

Observação

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 (Service Principal Name) da máquina (padrão) que é criada quando o computador é adicionado ao domínio do Active Directory, o que geralmente é feito executando o serviço sob a conta 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, é necessário implementar o protocolo Kerberos com negociação de credenciais, por vezes chamado de Kerberos "multi-etapas" ou "de passos múltiplos". 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:

  1. Implemente a delegação definindo AllowedImpersonationLevel como Delegation.

  2. Exigir a negociação do SSPI:

    1. Se você estiver usando associações padrão, defina a NegotiateServiceCredential propriedade como true.

    2. Se estiver a usar associações personalizadas, defina o atributo AuthenticationMode do elemento Security como SspiNegotiated.

  3. Exija que a negociação SSPI use Kerberos impedindo o uso de NTLM.

    1. Faça isso no código, com a seguinte instrução: ChannelFactory.Credentials.Windows.AllowNtlm = false

    2. Ou você pode fazer isso no arquivo de configuração definindo o allowNtlm atributo como false. Este atributo está contido nas <janelas>.

Protocolo NTLM

Negociar SSP retorna ao NTLM, mas o NTLM está desabilitado

A AllowNtlm propriedade é definida como false, o que faz com que o Windows Communication Foundation (WCF) tente 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.

O seguinte mostra como desativar 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 no início de sessão 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.

Ocorre um início de sessão NTLM anónimo, mas os inícios de sessão anónimos estão desativados 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 impersonação, consulte Delegação e Impersonação.

Como alternativa, o cliente é executado como um serviço do Windows, usando a conta incorporada SYSTEM.

Outros problemas

As credenciais do cliente não estão definidas corretamente

A autenticação do Windows usa a instância WindowsClientCredential retornada pela propriedade ClientCredentials da classe ClientBase<TChannel>, não a 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 implementando 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.

Ver também