Estoy teniendo una situación extraña aquí. Lo hice funcionar, pero no entiendo por qué. La situación es la siguiente:Punto final del cliente WCF: SecurityNegotiationException sin <dns>
Hay un servicio WCF que mi aplicación (un sitio web) tiene que llamar. El servicio WCF expone un netTcpBinding y requiere Transport Security (Windows). Cliente y servidor están en el mismo dominio, pero en servidores diferentes.
Así generar un resultado del cliente en la siguiente configuración (en su mayoría por defecto)
<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 hacer la llamada al servicio, me sale 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 acabo de alterar la configuración del cliente de esta manera:
<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 felizmente informa que fue llamado por Th una cuenta de servicio que aloja la AppPool para mi sitio web. Todo bien.
Mi pregunta ahora es: ¿por qué funciona esto? ¿Qué hace esto? Llegué a esta solución por mera prueba y error. Para mí, parece que toda la etiqueta <dns />
es decirle al cliente que use el DNS predeterminado para la autenticación, pero ¿no lo hace de todos modos?
ACTUALIZACIÓN
Así que después de un poco más de investigación y ensayo y error, que todavía no han encontrado una respuesta a este problema. En algunos casos, si no proporciono el <dns />
, aparece el error Credentials rejected
, pero si proporciono la configuración <dns value="whatever"/>
, funciona. ¿Por qué?
Teniendo tales problemas SSPI con nuestra comunicación Cliente/Servicio WCF durante bastante tiempo, pero nunca podría resolverse correctamente y solo ocurrió con algunos usuarios en algunas máquinas. La identidad de "DNS", incluso una vacía, parece hacer el tic ... simplemente wow. –