wcfkerberosspnegospnnegotiate

Is the default default SPN for a WCF Client `host/myhostname` or `http/myhostname` and why?


Due to this question the default behavior when no identity is specified is host/myhostname.

However this seems not totally true.

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.

The server is actually running under a domain user account. host/myhostname is specified but not for this user account, only for the machine account. http/myhostname is specified for this domain user account.

Lets look into three scenarios:

No identity is specified

I create the EndpointAddress with the following code:

new EndpointAddress(new Uri(endpoint))

In this scenario the following is happening:

Mannually set the identity to host/myhostname or a wrong string.

I create the EndpointAddress with the following code:

var identity = EndpointIdentity.CreateSpnIdentity(@"host/myhostname");
var endpointAddress = new EndpointAddress(new Uri(endpoint), identity); 

If host/myhostname would be the default setting, the code above would just explicit specify this default setting. So I would expect the same behavior. But this works. It seems the I fall back to NTLM. So there must be a difference.

This is whats happening:

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 EndpointAddress with this code:

var identity = EndpointIdentity.CreateSpnIdentity(@"thisIsTotallyWrongLoremIpsum");
var endpointAddress = new EndpointAddress(new Uri(endpoint), identity);

I also get the behavior above with the fallback to NTLM.

I correctly set the identity to http/myhostname

Now when I specify the SPN to http/myhostname which is set and seems to be the right choice due RFC 4559 it works. This is the configuration:

var identity = EndpointIdentity.CreateSpnIdentity(@"http/myhostname");
var endpointAddress = new EndpointAddress(new Uri(endpoint), identity);

And this is whats happening:


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:

  1. If the default identity is host/myhostname,
  2. it should make no difference to manually specify the identity to host/myhostname,
  3. but there is a difference
  4. so this can't be default identity.

So my questions are

  1. What is the actual default behavior, and
  2. why is http/myhostname not selected as the default SPN as it should due to RFC4559?

And/or did I understood something completely wrong?


Solution

  • There were two specific questions presented at the end of the problem statement; listing them below.

    Q. 1) What is the actual default behavior?

    A. If no identity is specified, and the client credential type is Windows, the default is SPN with the value set to the hostname part of the service endpoint address prefixed with the "host/" literal. This setting takes advantage of Windows Kerberos security if the service is running under one of the system accounts or under a domain account that has an associated SPN name with it and the computer is a member of a domain within an Active Directory environment.

    Q. 2) Why is http/myhostname not selected as the default SPN as it should due to RFC4559?

    A. With a web browser you would connect as http/myhostname. But with the WCF client, the default is to connect as host/myhostname as per the above. And it is definitely going to connect to host/myhostname under the scenario #2 where you set the identity to host/myhostname.

    Reference for Q1 and Q2 above: Service Identity and Authentication

    COMMENT: Fallback to NTLM occurs for a variety of reasons. The way to figure it out is to understand why Kerberos failed - SPN problems are the main cause. A great reference for diagnosing SPN problems is the Blog of Brian Murphy-Booth - The biggest mistake: ServicePrincipalName’s.

    After looking through the Brian Murphy blog, it was subsequently found by the original questioner that within the problem scenario, a port was being used. "The port is not used when the SPN is automatically determined. So http://foo.example.com:1234 leads to host/foo.example.com as SPN. And when the SPN does not exist it does fall back to NTLM and when the SPN does exist but not for the right user it throws the The target principal name is incorrect exception."