Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
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:
Determine si usa la autenticación de Windows. Si usa cualquier otro esquema, este tema no se aplica.
Si está seguro de que usa la autenticación de Windows, determine si la configuración de WCF usa Kerberos direct o Negotiate.
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
oMachineName\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:
Implemente la delegación estableciendo AllowedImpersonationLevel como Delegation.
Es necesaria la negociación de SSPI:
Si usa enlaces estándar, establezca la propiedad
NegotiateServiceCredential
entrue
.Si está utilizando enlaces personalizados, establezca el atributo
AuthenticationMode
del elementoSecurity
aSspiNegotiated
.
Es necesaria la negociación de SSPI para utilizar Kerberos al no permitir el uso de NTLM:
Haga esto en el código, con la siguiente instrucción:
ChannelFactory.Credentials.Windows.AllowNtlm = false
O bien puede hacerlo en el archivo de configuración estableciendo el atributo
allowNtlm
comofalse
. 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.