wcf configuration dns wcf-security wcf-client

Punto final del cliente WCF: SecurityNegotiationException sin<dns>



configuration wcf-security (3)

La "Identidad y autenticación del servicio" de MSDN explica que la sección de identidad de punto final habilita una precaución de seguridad del lado del cliente contra los esquemas de phishing.

Desde MSDN:

Después de que el cliente inicia una comunicación con un punto final y el servicio se autentica ante el cliente, el cliente compara el valor de identidad del punto final con el valor real que devolvió el proceso de autenticación del punto final. Si coinciden, el cliente está seguro de que se ha contactado con el punto final de servicio esperado. Esto funciona como una protección contra el phishing al evitar que un cliente sea redirigido a un punto final alojado por un servicio malicioso.

También vea "Ejemplo de identidad de servicio" de MSDN.

Estoy teniendo una situación extraña aquí. Lo tengo funcionando, pero no entiendo por qué. La situación es la siguiente:

Hay un servicio WCF que mi aplicación (un sitio web) tiene que llamar. El servicio WCF expone un netTcpBinding y requiere Seguridad de transporte (Windows). El cliente y el servidor están en el mismo dominio, pero en servidores diferentes.
Por lo tanto, generar un cliente da como resultado la siguiente configuración

<system.serviceModel> <bindings> <netTcpBinding> <binding name="MyTcpEndpoint" ...> <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" /> <security mode="Transport"> <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/> <message clientCredentialType="Windows" /> </security> </binding> </netTcpBinding> </bindings> <client> <endpoint address="net.tcp://localhost:xxxxx/xxxx/xxx/1.0" binding="netTcpBinding" bindingConfiguration="MyTcpEndpoint" contract="Service.IMyService" name="TcpEndpoint"/> </client> </system.serviceModel>

Cuando ejecuto el sitio web y hago la llamada al servicio, aparece el siguiente error:

System.ServiceModel.Security.SecurityNegotiationException: Either the target name is incorrect or the server has rejected the client credentials. ---> System.Security.Authentication.InvalidCredentialException: Either the target name is incorrect or the server has rejected the client credentials. ---> System.ComponentModel.Win32Exception: The logon attempt failed --- End of inner exception stack trace --- at System.Net.Security.NegoState.EndProcessAuthentication(IAsyncResult result) at System.Net.Security.NegotiateStream.EndAuthenticateAsClient(IAsyncResult asyncResult) at System.ServiceModel.Channels.WindowsStreamSecurityUpgradeProvider.WindowsStreamSecurityUpgradeInitiator.InitiateUpgradeAsyncResult.OnCompleteAuthenticateAsClient(IAsyncResult result) at System.ServiceModel.Channels.StreamSecurityUpgradeInitiatorAsyncResult.CompleteAuthenticateAsClient(IAsyncResult result) --- End of inner exception stack trace --- Server stack trace: at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result) at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result) at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result) ....

Ahora, si tan solo altero la configuración del cliente así:

<endpoint address="net.tcp://localhost:xxxxx/xxxx/xxx/1.0" binding="netTcpBinding" bindingConfiguration="MyTcpEndpoint" contract="Service.IMyService" name="TcpEndpoint"> <identity> <dns /> </identity> </endpoint>

todo funciona y mi servidor informa alegremente que la cuenta de servicio que aloja el AppPool para mi sitio web lo llamó. Todo bien.

Mi pregunta ahora es: ¿por qué funciona esto? ¿Qué hace esto? Llegué a esta solución por simple prueba y error. A mi parecer, todo lo que hace la etiqueta <dns /> es decirle al cliente que use el DNS predeterminado para la autenticación, pero ¿no lo hace de todos modos?

ACTUALIZAR
Así que después de un poco más de investigación y prueba y error, todavía no he encontrado una respuesta a este problema. En algunos casos, si no proporciono el <dns /> , obtengo el error de Credentials rejected , pero si proporciono la configuración de <dns value="whatever"/> , funciona. ¿Por qué?


No es una respuesta, pero el mismo "truco" funciona si crea el EndpointAddress a través del código:

// does fail on some machines for some users // (I have no explanation here - just crazy) var address = new EndpointAddress(new Uri(url)); // will work and the dns entry doesn''t matter address = new EndpointAddress(new Uri(url), UpnEndpointIdentity.CreateDnsIdentity(""));

Es extraño y no sé por qué esto funciona, pero parece ayudar.


<dns/> etiqueta <dns/> permite al cliente verificar la identidad del servidor. Por ejemplo, si dice <dns value="google.com"/> verificará que el servidor WCF proporcione la identidad de google.com. Ya que dices <dns/> probablemente solo permita que todos te sirvan.

Más información en Service Identity and Authentication