title: WCF client endpoint: SecurityNegotiationException without <dns>
body: <p>I'm having a strange situation here. I got it working, but I don't understand why.
  Situation is as follows:  </p>
  
  <p>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.<br>
  So generating a client results in the following config (mostly defaults)</p>
  
  <pre><code>&lt;system.serviceModel&gt;
      &lt;bindings&gt;
        &lt;netTcpBinding&gt;
           &lt;binding name="MyTcpEndpoint" ...&gt;          
                &lt;reliableSession ordered="true" inactivityTimeout="00:10:00"
                                enabled="false" /&gt;
               &lt;security mode="Transport"&gt;
                  &lt;transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/&gt;
                  &lt;message clientCredentialType="Windows" /&gt;
              &lt;/security&gt;
          &lt;/binding&gt;
        &lt;/netTcpBinding&gt;
      &lt;/bindings&gt;
      &lt;client&gt; 
          &lt;endpoint address="net.tcp://localhost:xxxxx/xxxx/xxx/1.0" 
                     binding="netTcpBinding" bindingConfiguration="MyTcpEndpoint" 
                     contract="Service.IMyService" name="TcpEndpoint"/&gt;
      &lt;/client&gt;
  &lt;/system.serviceModel&gt;
  </code></pre>
  
  <p>When I run the website and make the call to the service, I get the following error:  </p>
  
  <pre><code>System.ServiceModel.Security.SecurityNegotiationException: Either the target name is incorrect or the server has rejected the client credentials. ---&gt; System.Security.Authentication.InvalidCredentialException: Either the target name is incorrect or the server has rejected the client credentials. ---&gt; 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)
  ....
  </code></pre>
  
  <p>Now, if I just alter the configuration of the client like so:</p>
  
  <pre><code>    &lt;endpoint address="net.tcp://localhost:xxxxx/xxxx/xxx/1.0" 
                 binding="netTcpBinding" bindingConfiguration="MyTcpEndpoint" 
                 contract="Service.IMyService" name="TcpEndpoint"&gt;
          &lt;identity&gt;
              &lt;dns /&gt;
          &lt;/identity&gt; 
    &lt;/endpoint&gt;
  </code></pre>
  
  <p>everything works and my server happily reports that it got called by the service account which hosts the AppPool for my website. All good.</p>
  
  <p>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 <code>&lt;dns /&gt;</code> tag does is tell the client to use the default DNS for authentication, but doesn't it do that anyway?</p>
  
  <p><strong>UPDATE</strong><br>
  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 <code>&lt;dns /&gt;</code>, I get the <code>Credentials rejected</code> error, but if I provide the <code>&lt;dns value="whatever"/&gt;</code>config, it works. Why?</p>