2010-05-06 19 views
16

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é?

+0

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. –

Respuesta

12

<dns/> etiqueta permite al cliente verificar la identidad del servidor. Por ejemplo, si dijo <dns value="google.com"/>, verificaría que el servidor WCF proporciona la identidad de google.com. Como dices <dns/>, probablemente solo permita que todos te atiendan.

Más información en Service Identity and Authentication

+0

Bueno, después de volver a leer esa página y probar algunas configuraciones diferentes, todavía no se ha resuelto. Incluso si proporciono 'my-crappy-unexisting-dummy-domain.com', todavía funciona.Pensé que debía tratar de hacer la solicitud y luego regresar a un valor predeterminado, pero no puedo encontrar nada en el registro que sugiera que el servidor DNS o el servidor de aplicaciones incluso intentaron autenticarse contra ese dominio ... Así que mi pregunta es todavía sin resolver. ¡Gracias por ayudarme! – RoelF

+0

Creo que necesitaría tener un certificado con un nombre de dominio para que el cliente se autentique. – Vitalik

+0

+1 Hola, ¿podrías explicarme esto? Entonces, ¿qué significa si el dns tiene un valor = "localhost"? – Lamps

5

de MSDN "Service Identity and Authentication" explica que la sección de la identidad de punto final permite una precaución de seguridad del lado del cliente frente a esquemas de phishing.

De MSDN:

After the client initiates a communication to an endpoint and the service authenticates itself to the client, the client compares the endpoint identity value with the actual value the endpoint authentication process returned. If they match, the client is assured it has contacted the expected service endpoint. This functions as a protection against phishing by preventing a client from being redirected to an endpoint hosted by a malicious service.

Véase también MSDN de "Service Identity Sample".

0
No

una respuesta, pero el mismo "truco" funciona si crea la EndpointAddress a través de 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 está funcionando, pero parece que ayuda.

Cuestiones relacionadas