Compartir a través de


Depuración de errores de autenticación de Windows

Cuando se usa la autenticación de Windows como mecanismo de seguridad, la interfaz del proveedor de soporte técnico de seguridad (SSPI) controla los procesos de seguridad. Cuando se producen errores de seguridad en la capa SSPI, Windows Communication Foundation (WCF) los expone. En este tema se proporciona un marco y un conjunto de preguntas para ayudar 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 soporte de seguridad Negotiate (SSP), que realiza la autenticación mutua Kerberos entre el cliente y el servicio. Si el protocolo Kerberos no está disponible, WCF vuelve de forma predeterminada a NT LAN Manager (NTLM). Sin embargo, puede configurar WCF para que use solo el protocolo Kerberos (y para producir una excepción si Kerberos no está disponible). También puede configurar WCF para que use formularios restringidos del protocolo Kerberos.

Depuración de la metodología

El método básico es el siguiente:

  1. Determine si usa la autenticación de Windows. Si usa cualquier otro esquema, este tema no se aplica.

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

  3. Una vez que haya determinado si la configuración usa el protocolo Kerberos o NTLM, puede comprender los mensajes de error en el contexto correcto.

Disponibilidad del protocolo Kerberos y NTLM

El SSP de Kerberos requiere que un controlador de dominio actúe como centro de distribución de claves (KDC) de Kerberos. El protocolo Kerberos solo está disponible cuando el cliente y el servicio usan identidades de dominio. En otras combinaciones de cuentas, se usa NTLM, como se resume en la tabla siguiente.

Los encabezados de tabla muestran posibles tipos de cuenta usados por el servidor. En la columna izquierda se muestran los posibles tipos de cuenta usados 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
Máquina de dominio NTLM NTLM Kerberos Kerberos

En concreto, los cuatro tipos de cuenta incluyen:

  • Usuario local: perfil de usuario exclusivo de máquina. Por ejemplo: MachineName\Administrator o MachineName\ProfileName.

  • Sistema local: sistema de cuenta integrada en un equipo que no está unido a un dominio.

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

  • Equipo de dominio: proceso con identidad de máquina que se ejecuta en una máquina unida a un dominio de Windows. Por ejemplo: MachineName\Network Service.

Nota:

La credencial de servicio se captura cuando se llama al Open método de la ServiceHost clase . La credencial de cliente se lee cada vez que el cliente envía un mensaje.

Problemas comunes de autenticación de Windows

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

Protocolo Kerberos

Problemas de SPN/UPN con el protocolo Kerberos

Cuando se usa la autenticación de Windows y SSPI usa o negocia el protocolo Kerberos, la dirección URL que usa el punto de conexión de cliente debe incluir el nombre de dominio completo del host del 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 de usuario (UPN) de la cuenta en la que el servicio se ejecuta 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 Service Identity and Authentication.

En escenarios de equilibrio de carga, como granjas de servidores web o jardines web, una práctica habitual 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 en esa cuenta.

Para obtener un SPN para la cuenta del servicio, debe ser administrador de dominio de Active Directory. Para obtener más información, consulte Complemento técnico de Kerberos para Windows.

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

Esto ocurre cuando la propiedad ClientCredentialType se establece en Windows y la propiedad NegotiateServiceCredential se establece en false, 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 negociación de 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 negociación de credenciales, siga estos pasos:

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

  2. Es necesaria la negociación de SSPI:

    1. Si usa enlaces estándar, establezca la propiedad NegotiateServiceCredential en true.

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

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

    1. Haga esto 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 está incluido en las <ventanas>.

Protocolo NTLM

Negociar SSP retrocede hasta NTLM, pero NTLM está deshabilitado

La propiedad AllowNtlm se establece en false, lo que hace que Windows Communication Foundation (WCF) intente lanzar una excepción si se usa NTLM. Establecer esta propiedad en false puede no impedir que las credenciales NTLM se envíen 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 de cliente no son válidas en el servicio. Compruebe que el nombre de usuario y la contraseña están configurados correctamente y corresponden a una cuenta que se conoce en el equipo donde se ejecuta el servicio. NTLM usa las credenciales especificadas para iniciar sesión en el equipo del servicio. Aunque las credenciales pueden ser válidas en el equipo donde se ejecuta el cliente, se producirá un error en este inicio de sesión si las credenciales no son válidas en el equipo del servicio.

Se produce el inicio de sesión NTLM anónimo, pero los inicios de sesión anónimos están deshabilitados de forma predeterminada

Al crear un cliente, la AllowedImpersonationLevel propiedad se establece en Anonymous, como se muestra en el ejemplo siguiente, pero de forma predeterminada el servidor no permite los accesos anónimos. Esto ocurre porque el valor predeterminado de la AllowAnonymousLogons propiedad de la WindowsServiceCredential clase es false.

El código de cliente siguiente intenta habilitar inicios de sesión anónimos (tenga en cuenta 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 de servicio siguiente cambia el valor predeterminado para habilitar los inicios 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, vea Delegación y suplantación.

Como alternativa, el cliente se ejecuta como servicio de Windows mediante el sistema de cuenta integrada.

Otros problemas

Las credenciales de cliente no se establecen correctamente

La autenticación de Windows usa la instancia WindowsClientCredential devuelta por la propiedad ClientCredentials de la clase ClientBase<TChannel>, no la 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!

A continuación 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 usa como servidor: Windows XP Home Edition, Windows XP Media Center Edition y las ediciones Windows Vista Home.

Desarrollo e implementación con identidades diferentes

Si desarrolla la aplicación en una máquina e implementa en otra y usa diferentes tipos de cuenta para autenticarse en cada máquina, puede experimentar un comportamiento diferente. Por ejemplo, supongamos que desarrolla la aplicación en una máquina Windows XP Pro mediante el SSPI Negotiated modo de autenticación. Si usa una cuenta de usuario local con la que autenticarse, se usará el protocolo NTLM. Una vez desarrollada la aplicación, se implementa el servicio en una máquina de Windows Server 2003 donde se ejecuta en una cuenta de dominio. En este momento, el cliente no podrá autenticar el servicio porque usará Kerberos y un controlador de dominio.

Consulte también