Depuración de errores de autenticación de Windows

Cuando se utiliza la autenticación de Windows como un mecanismo de seguridad, la interfaz del proveedor de compatibilidad para seguridad (SSPI) controla los procesos de seguridad. Cuando los errores de seguridad se producen en la capa de SSPI, Windows Communication Foundation los muestra. En este tema se proporciona un marco y conjunto de cuestiones que le ayudarán a diagnosticar los errores.

Para obtener información general sobre el protocolo Kerberos, consulte Explicación de Kerberos; para obtener información general sobre SSPI, consulte SSPI.

Para la autenticación de Windows, WCF normalmente usa el proveedor de compatibilidad para seguridad (SSP) Negotiate, que realiza la autenticación mutua de Kerberos entre el cliente y el servicio. Si el protocolo Kerberos no está disponible, WCF recurrirá a NT LAN Manager (NTLM) de forma predeterminada. Sin embargo, puede configurar WCF para usar solo el protocolo Kerberos (y para que se produzca una excepción si Kerberos no está disponible). También puede configurar WCF para usar formularios restringidos del protocolo Kerberos.

Depuración de la metodología

El método básico es el siguiente:

  1. Determine si está utilizando la autenticación de Windows. Si está utilizando cualquier otro esquema, no se aplicará este tema.

  2. Si está seguro de que usa la autenticación de Windows, determine si la configuración de WCF usa Kerberos directo o Negotiate.

  3. Cuando haya determinado si su configuración está utilizando el protocolo Kerberos o NTLM, podrá entender los mensajes de error en el contexto correcto.

Disponibilidad del protocolo Kerberos y NTLM

SSP de Kerberos exige que un controlador de dominio actúe como el Centro de distribución de claves de Kerberos (KDC). El protocolo Kerberos solo está disponible cuando el cliente y el servicio están utilizando las identidades del dominio. En otras combinaciones de cuentas, se utiliza NTLM, tal y como se resume en la tabla siguiente.

Los encabezados de la tabla muestran posibles tipos de cuenta utilizados por el servidor. La columna izquierda muestra posibles tipos de cuenta utilizados por el cliente.

Usuario local Sistema local Usuario de dominio Equipo del dominio
Usuario local NTLM NTLM NTLM NTLM
Sistema local NTLM anónimo NTLM anónimo NTLM anónimo NTLM anónimo
Usuario de dominio NTLM NTLM Kerberos Kerberos
Equipo del dominio NTLM NTLM Kerberos Kerberos

Específicamente, los cuatro tipos de cuenta incluyen:

  • Usuario local: perfil de usuario de solo el equipo. Por ejemplo: MachineName\Administrator o MachineName\ProfileName.

  • Sistema local: el SISTEMA de cuentas integrado en un equipo que no está unido a un dominio.

  • Usuario del dominio: una cuenta de usuario en un dominio de Windows. Por ejemplo: DomainName\ProfileName.

  • Equipo del dominio: un proceso con la identidad del equipo en ejecución en un equipo unido a un dominio de Windows. Por ejemplo: MachineName\Network Service.

Nota:

Se captura la credencial de servicio cuando se llama al método Open de la clase ServiceHost. Se lee la credencial del cliente siempre que el cliente envíe un mensaje.

Problemas comunes de autenticación de Windows

En esta sección se tratan algunos problemas comunes de autenticación de Windows y las soluciones posibles.

Protocolo Kerberos

Problemas de SPN/UPN con el protocolo Kerberos

Cuando se utiliza la autenticación de Windows y se usa o se negocia el protocolo Kerberos mediante SSPI, la dirección URL que el punto de conexión de cliente usa debe incluir el nombre de dominio completo del host de servicio dentro de la dirección URL del servicio. Esto supone que la cuenta con la que se ejecuta el servicio tiene acceso a la clave del nombre de entidad de seguridad de servicio (SPN) de equipo (valor predeterminado) que se crea cuando el equipo se agrega al dominio de Active Directory, que se hace por lo general ejecutando el servicio en la cuenta Servicio de red. Si el servicio no tiene acceso a la clave SPN del equipo, debe proporcionar el SPN correcto o el nombre principal del usuario (UPN) de la cuenta con la que se está ejecutando el servicio en la identidad del punto de conexión del cliente. Para obtener más información sobre cómo funciona WCF con SPN y UPN, consulte Identidad del servicio y autenticación.

En los escenarios de equilibrio de carga, como las granjas de servidores web o los conjuntos de procesos de aplicación web, una práctica común es definir una cuenta única para cada aplicación, asignar un SPN a esa cuenta y asegurarse de que todos los servicios de la aplicación se ejecutan con esa cuenta.

Para obtener un SPN para la cuenta de servicio, necesita ser un administrador de dominios de Active Directory. Para obtener más información, consulte Suplemento técnico de Kerberos para Windows.

El protocolo Kerberos Direct requiere que el servicio se ejecute en una cuenta de equipo de dominio

Esto se produce cuando la propiedad ClientCredentialType está establecida como Windows y la propiedad NegotiateServiceCredential está establecida como false, tal y como se muestra en el código siguiente.

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 solucionarlo, ejecute el servicio mediante una cuenta de equipo de dominio, como el servicio de red, en un equipo unido a un dominio.

La delegación requiere la negociación de las credenciales

Para utilizar el protocolo de autenticación Kerberos con la delegación, debe implementar el protocolo Kerberos con negociación de la credencial (a veces denominado Kerberos de "autenticación mutua" o "de varios pasos"). Si implementa la autenticación de Kerberos sin la negociación de la credencial (denominada en ocasiones Kerberos de "un disparo" o "fase única"), se producirá una excepción.

Para implementar Kerberos con la negociación de credenciales, lleve a cabo los pasos siguientes:

  1. Implemente la delegación estableciendo AllowedImpersonationLevel como Delegation.

  2. Es necesaria la negociación de SSPI:

    1. Si está usando enlaces estándar, establezca la propiedad NegotiateServiceCredential como true.

    2. Si está utilizando los enlaces personalizados, establezca el atributo AuthenticationMode del elemento Security como SspiNegotiated.

  3. Es necesaria la negociación de SSPI para utilizar Kerberos al no permitir el uso de NTLM:

    1. Realice esta acción en el código, con la siguiente instrucción: ChannelFactory.Credentials.Windows.AllowNtlm = false

    2. O bien puede hacerlo en el archivo de configuración estableciendo el atributo allowNtlm como false. Este atributo se incluye en <windows>.

Protocolo NTLM

Negociar SSP retrocede hasta NTLM, pero NTLM está deshabilitado

La propiedad AllowNtlm está establecida en false, lo que hace que Windows Communication Foundation (WCF) realice un mayor esfuerzo por producir una excepción si se usa NTLM. Aunque se establezca esta propiedad en false, es posible que las credenciales NTLM se envíen igualmente a través de la conexión.

A continuación, se muestra cómo deshabilitar el retroceso a NTLM.

CalculatorClient cc = new
    CalculatorClient("WSHttpBinding_ICalculator");
cc.ClientCredentials.Windows.AllowNtlm = false;
Dim cc As New CalculatorClient("WSHttpBinding_ICalculator")
cc.ClientCredentials.Windows.AllowNtlm = False

Error en el inicio de sesión de NTLM

Las credenciales del cliente no son válidas en el servicio. Compruebe que el nombre de usuario y la contraseña se hayan establecido correctamente y que se corresponde con una cuenta que es conocida en el equipo en el que se está ejecutando el servicio. NTLM utiliza las credenciales especificadas para iniciar sesión en el equipo del servicio. Mientras las credenciales pueden ser válidas en el equipo donde el cliente se está ejecutando, se producirá un error en este inicio de sesión si las credenciales no son válidas en el equipo del servicio.

Se inicia la sesión anónima de NTLM, aunque los inicios de sesión anónimos se deshabilitan de manera predeterminada

Al crear un cliente, la propiedad AllowedImpersonationLevel se establece como Anonymous, tal y como se muestra en el ejemplo siguiente, aunque de forma predeterminada el servidor no permite los inicio de sesión anónimos. Esto solo se produce cuando el valor predeterminado de la propiedad AllowAnonymousLogons de la clase WindowsServiceCredential sea false.

El código de cliente siguiente intenta habilitar los inicios de sesión anónimos (observe que la propiedad predeterminada es 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

El código del servicio siguiente cambia el valor predeterminado para habilitar los inicio de sesión anónimos por el 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 obtener más información sobre la suplantación, consulte Delegación y suplantación.

Por otra parte, el cliente se está ejecutando como un servicio de Windows, utilizando el SISTEMA de cuentas integrado.

Otros problemas

No se establecen las credenciales del cliente correctamente

La autenticación de Windows utiliza la instancia WindowsClientCredential devuelta por la propiedad ClientCredentials de la clase ClientBase<TChannel>, no UserNamePasswordClientCredential. A continuación se muestra un ejemplo incorrecto.

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!

En el ejemplo siguiente se muestra el ejemplo correcto.

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 no está disponible

Los siguientes sistemas operativos no admiten la autenticación de Windows cuando se ha usado como un servidor: Windows XP Home Edition, Windows XP Media Center Edition y Windows Vista Home Editions.

Desarrollo e implementación con distintas identidades

Si desarrolla una aplicación en un equipo y la implementa en otro, y utiliza tipos de cuentas diferentes para autenticarse en cada equipo, el comportamiento puede ser diferente. Supongamos, por ejemplo, que desarrolla una aplicación en un equipo Windows XP Pro con el modo de autenticación SSPI Negotiated. Si utiliza una cuenta de usuario local para autenticarse, se utilizará el protocolo NTLM. Una vez desarrollada la aplicación, implementa el servicio en un equipo Windows Server 2003, donde se ejecuta bajo una cuenta de dominio. En este punto, el cliente no podrá autenticar el servicio, ya que estará utilizando Kerberos y un controlador de dominio.

Consulte también