Is the default default SPN for a WCF Client `host/myhostname` or `http/myhostname` and why?
<p>Due to <a href="https://stackoverflow.com/questions/24966779/wcf-client-default-spn-generation">this question</a> the default behavior when no <code>identity</code>  is specified is <code>host/myhostname</code>.</p>
<p>However this seems not totally true.</p>
<p>I have a SOAP WCF Service (it's a Dynamics NAV Webservice but this should not matter for the following since the question is totally about client perspective) that does not work if I don't specify any identity.</p>
<p>The server is actually running under a domain user account.
<code>host/myhostname</code> is specified but not for this user account, only for the machine account.
<code>http/myhostname</code> is specified for this domain user account.</p>
<p>Lets look into three scenarios:</p>
<h2>No identity is specified</h2>
<p>I create the <code>EndpointAddress</code> with the following code:</p>
<pre><code>new EndpointAddress(new Uri(endpoint))
</code></pre>
<p>In this scenario the following is happening:</p>
<ul>
<li>HTTP POST without <code>Authorization </code> header.</li>
<li>Response with <code>WWW-Authenticate: Negotiate</code>.</li>
<li>HTTP POST with <code>Authorization: Negotiate XXX</code> header. <code>XXX</code> are 1584 BASE64 encoded bytes, starting with <code>96 130 6</code>. I can't find any readable ASCII inside it.</li>
<li>Response with <code>Authorization: Negotiate XXX</code> header. <code>XXX</code> are 126 BASE64 encoded bytes. I can't find any readable ASCII inside it.</li>
<li>HTTP POST with <code>Authorization: Negotiate XXX</code> header. <code>XXX</code> are 1527 BASE64 encoded bytes. I can't find any readable ASCII inside it.</li>
<li>Response with <code>WWW-Authenticate: Negotiate XXX</code> header. <code>XXX</code> are 113 BASE64 encoded bytes. I can't find any readable ASCII inside it.</li>
<li>At this Point the client throws an exception. The inner exception message is <code>The target principal name is incorrect</code>.</li>
</ul>
<h2>Mannually set the identity to <code>host/myhostname</code> or a wrong string.</h2>
<p>I create the EndpointAddress with the following code:</p>
<pre><code>var identity = EndpointIdentity.CreateSpnIdentity(@&quot;host/myhostname&quot;);
var endpointAddress = new EndpointAddress(new Uri(endpoint), identity); 
</code></pre>
<p>If <code>host/myhostname</code> would be the default setting, the code above would just explicit specify this default setting. So I would <strong>expect the same behavior</strong>. But this works. It seems the I fall back to NTLM. So there <strong>must be a difference</strong>.</p>
<p>This is whats happening:</p>
<ul>
<li>HTTP POST without <code>Authorization </code> header.</li>
<li>Response with <code>WWW-Authenticate: Negotiate</code>.</li>
<li>HTTP POST with <code>Authorization: Negotiate XXX</code> where XXX are 40 BASE64 encoded bytes. The first bytes are the ASCII letters <code>NTLMSSP</code>.</li>
<li>Response with <code>WWW-Authenticate: Negotiate XXX</code> where XXX are 270 BASE64 encoded bytes. The first bytes are the ASCII letters <code>NTLMSSP</code>. Also the FQDN seems to be encoded as ASCII.</li>
<li>HTTP POST with <code>Authorization: Negotiate XXX</code>, where XXX are 590 BASE64 encoded bytes. No ASCII letters this time tho.</li>
<li>Response with the Payload.</li>
</ul>
<p>An interesting fact: If I specify the identity to any wrong String, I have the exactly same behavior. So for example if I specify the <code>EndpointAddress</code> with this code:</p>
<pre><code>var identity = EndpointIdentity.CreateSpnIdentity(@&quot;thisIsTotallyWrongLoremIpsum&quot;);
var endpointAddress = new EndpointAddress(new Uri(endpoint), identity);
</code></pre>
<p>I also get the behavior above with the fallback to NTLM.</p>
<h2>I correctly set the identity to <code>http/myhostname</code></h2>
<p>Now when I specify the SPN to <code>http/myhostname</code> which is set and seems to be the right choice due <a href="https://www.rfc-editor.org/rfc/rfc4559" rel="nofollow noreferrer">RFC 4559</a> it works. This is the configuration:</p>
<pre><code>var identity = EndpointIdentity.CreateSpnIdentity(@&quot;http/myhostname&quot;);
var endpointAddress = new EndpointAddress(new Uri(endpoint), identity);
</code></pre>
<p>And this is whats happening:</p>
<ul>
<li>HTTP POST without <code>Authorization </code> header.</li>
<li>Response with <code>WWW-Authenticate: Negotiate</code>.</li>
<li>HTTP POST with <code>Authorization: Negotiate XXX</code> header. XXX are 1580 BASE64 encoded bytes. No ASCI signs.</li>
<li>Response with the Payload.</li>
</ul>
<hr />
<p>This question is not about hot to get it to work but about understanding.
Whats confusing me is the difference between the first and the second example. My thoughts are:</p>
<ol>
<li>If the default identity is <code>host/myhostname</code>,</li>
<li>it should make no difference to manually specify the identity to <code>host/myhostname</code>,</li>
<li>but there is a difference</li>
<li>so this can't be default identity.</li>
</ol>
<p>So my questions are</p>
<ol>
<li>What is the actual default behavior, and</li>
<li>why is <code>http/myhostname</code> not selected as the default SPN as it should due to RFC4559?</li>
</ol>
<p>And/or did I understood something completely wrong?</p>