Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF client endpoint: SecurityNegotiationException without <dns>

Tags:

I'm having a strange situation here. I got it working, but I don't understand why. Situation is as follows:

There is a WCF service which my application (a website) has to call. The WCF service exposes a netTcpBinding and requires Transport Security (Windows). Client and server are in the same domain, but on different servers.
So generating a client results in the following config (mostly defaults)

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

When I run the website and make the call to the service, I get the following 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) .... 

Now, if I just alter the configuration of the client like so:

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

everything works and my server happily reports that it got called by the service account which hosts the AppPool for my website. All good.

My question now is: why does this work? What does this do? I got to this solution by mere trial-and-error. To me it seems that all the <dns /> tag does is tell the client to use the default DNS for authentication, but doesn't it do that anyway?

UPDATE
So after some more research and trial-and-error, I still haven't found an answer to this problem. In some cases, if I don't provide the <dns />, I get the Credentials rejected error, but if I provide the <dns value="whatever"/>config, it works. Why?

like image 289
RoelF Avatar asked May 06 '10 14:05

RoelF


2 Answers

<dns/> tag allows the client to verify the server identity. For example if you said <dns value="google.com"/> it would verify that the WCF server provides google.com identity. Since you say <dns/> it probably just allows everybody to serve you.

More info at Service Identity and Authentication

like image 168
Vitalik Avatar answered Sep 24 '22 01:09

Vitalik


MSDN's "Service Identity and Authentication" explains that the endpoint identity section enables a client-side security precaution against phishing schemes.

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

Also see MSDN's "Service Identity Sample".

like image 38
Rana Ian Avatar answered Sep 24 '22 01:09

Rana Ian