Necesito llamar a un servicio de WCF programmatically. El servicio puede hospedarse con ya sea autenticación NTLM o Kerberos y debe funcionar bajo cualquiera de ellos. Es decir, si falla la conexión al servicio a través de Kerberos, debe recurrir a NTLM.¿Cómo escribir código que llame a un servicio WCF y que retroceda desde Kerberos a NTLM si es necesario?
Aquí está el código que estoy usando para Kerberos de autenticación (si es relevante, el servicio está alojado en SharePoint 2010 y se está llamando desde una pieza de la tela):
public static SiteMembershipSvc.SiteMembershipServiceClient InitialiseSiteMembershipService(string url)
{
var binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
url = url.EndsWith("/") ? url + SiteMembershipAddress : url + "/" + SiteMembershipAddress;
var endpoint = new EndpointAddress(url);
var proxy = new SiteMembershipSvc.SiteMembershipServiceClient(binding, endpoint);
proxy.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
return proxy;
}
llamar a un método en el proxy cuando es ejecutado en un entorno NTLM da el error:
The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'NTLM'.
Nota: la dirección URL puede estar en otra aplicación web en otro servidor. No puedo verificar en qué autenticación se ejecuta la aplicación web de la parte web y asumir que es igual a donde se aloja el servicio WCF.
¿Cómo puedo (automática o manualmente) garantizar que la autenticación vuelva desde Kerberos a NTLM cuando falla?
Actualización:
Como se mencionó, el error de autenticación se produce cuando se llama a un método web. Sin embargo, no quiero esperar tanto, ya que hay varios métodos web en el servicio llamados desde varios lugares. Me gustaría probar la autenticación en el punto donde está configurado el proxy (en el fragmento de código anterior).
He intentado usar proxy.Open()
pero eso no parece causar la falla.
Bueno, es más que quiero que pruebe Kerberos primero y si eso falla, entonces use NTLM. Esperaba usar Kerberos auth automáticamente haría esto pero parece que no. –
Mi primera suposición también. La forma de pensarlo es si se confió en algún servicio de la empresa, entonces podrías tener un rogue de servicio robando credenciales, suplantando y haciendo cosas malas. El SPN obliga al administrador de la empresa a decir que se confía en que este servicio tenga su credencial de kerberos; de lo contrario, no lo solicite. – Spence
Eso es bueno saber. He reformulado la pregunta un poco, ya que no creo que haya sido clara. Necesito el elemento web para 'seleccionar automáticamente' la autenticación correcta dependiendo de si el servicio está alojado en Kerberos o autenticación de Windows. –