2

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:

  • HTTP POST without Authorization header.
  • Response with WWW-Authenticate: Negotiate.
  • HTTP POST with Authorization: Negotiate XXX header. XXX are 1584 BASE64 encoded bytes, starting with 96 130 6. I can't find any readable ASCII inside it.
  • Response with Authorization: Negotiate XXX header. XXX are 126 BASE64 encoded bytes. I can't find any readable ASCII inside it.
  • HTTP POST with Authorization: Negotiate XXX header. XXX are 1527 BASE64 encoded bytes. I can't find any readable ASCII inside it.
  • Response with WWW-Authenticate: Negotiate XXX header. XXX are 113 BASE64 encoded bytes. I can't find any readable ASCII inside it.
  • At this Point the client throws an exception. The inner exception message is The target principal name is incorrect.

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:

  • HTTP POST without Authorization header.
  • Response with WWW-Authenticate: Negotiate.
  • HTTP POST with Authorization: Negotiate XXX where XXX are 40 BASE64 encoded bytes. The first bytes are the ASCII letters NTLMSSP.
  • Response with WWW-Authenticate: Negotiate XXX where XXX are 270 BASE64 encoded bytes. The first bytes are the ASCII letters NTLMSSP. Also the FQDN seems to be encoded as ASCII.
  • HTTP POST with Authorization: Negotiate XXX, where XXX are 590 BASE64 encoded bytes. No ASCII letters this time tho.
  • Response with the Payload.

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:

  • HTTP POST without Authorization header.
  • Response with WWW-Authenticate: Negotiate.
  • HTTP POST with Authorization: Negotiate XXX header. XXX are 1580 BASE64 encoded bytes. No ASCI signs.
  • Response with the Payload.

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?

Community
  • 1
  • 1
Lux
  • 17,835
  • 5
  • 43
  • 73
  • "When I specify the SPN and set it to host/myhostname which is not registered or anything else, I can literally use the string anything, it seems that I fall back to NTLM.". There MUST be a registered SPN in order for Kerberos authentication to work. SPNs are how Kerberos clients find Kerberos-protected services. No SPN means Kerberos auth will never work and you will likely fallback to NTLM (depending on policy) according to Microsoft IWA model. SPNs should be fully DNS qualified, otherwise the client is at risk to fallback to NTLM. http/myhostname if it doesn't exist - will always fail – T-Heron Dec 03 '16 at 15:20
  • One other thing - http/hostname doesn't exist by default, while host/hostname does. – T-Heron Dec 03 '16 at 15:35
  • @THeron well, sure there must be an registered SPN. But why does WCF deny the authentication when I don't specify an SPN, and falls back to NTLM when I specify a non existing one? – Lux Dec 04 '16 at 04:12
  • This case is a great example of why, you should setup the SPN on your application server linked to an AD domain *user* account. Without specifying anything up front when you setup Windows web servers, SPNs will be constructed using host/myhostname and Windows authentication will try that one. This is what you meant by "the default behavior when no identity is specified is host/myhostname." On your statement "SOAP WCF Service does not work if I don't specify any identity". So setup the identity using a manually created SPN like HTTP/myhostname.mydomain.local and everything should work. – T-Heron Dec 04 '16 at 12:38
  • @THeron this is just wrong. As I've shown there *is* a difference from specifying `host/myhostname` as identity and specifying none. So `host/myhostname` **is not the default behavior**. What is the actual default behavior? – Lux Dec 04 '16 at 22:28
  • What I've seen is only your interpretation of a scenario. Do you have any saved packet captures or error log messages backing up your assertions? If you make your packet captures/log snippets available somehow, say on DropBox, I will analyze them and come back with further comments. Until that time, I wish to discontinue going back and forth on this until I see some concrete examples of items backing up these claims. I am interested to continue digging into this. – T-Heron Dec 04 '16 at 22:46
  • 1
    @THeron Hm, maybe I was unclear with my question. I've edited to to clarify things up. The data are extracted from the packages with `fiddler2`. Sadly I can't give out binary packages, but if you tell me what information could be helpful I will be happy to provide them. I'm thankful for your help. Can you now follow my conclusion that `host/myhostname` can't be the default identity? – Lux Dec 04 '16 at 23:20
  • I've seen you've just opened a bounty on this question. This might attract the attention of Michael-O or Samson Scharfrichter, the two best Kerberos people I've seen on SO since joining. Else, I will re-read your question carefully sometime later this week, do some reference checking on it, and respond after that. I've also up-voted your last comment, as opening a bounty is cool stuff. :-) – T-Heron Dec 04 '16 at 23:34
  • Update: The post you cited at the begging of your question "http://stackoverflow.com/questions/24966779/wcf-client-default-spn-generation" was from a user with only a 33 reputation score. Not to discredit it on that basis alone but, the answer was never even accepted nor ever voted up and has been sitting for more than a year and a half. Though, it was never voted down either. I'm starting to research, this will take a few days, as I am also busy doing other stuff. – T-Heron Dec 06 '16 at 00:22
  • Question: On scenario #2, in which you said it was working when it shouldn't have been working after setting intentionally wrong string. So what happens after you restart the app server, clear client web browser cache, and then re-launch browser and try again? In such a case, authentication should expectedly fail. – T-Heron Dec 06 '16 at 04:48
  • @THeron I don't access with a web browser. I'm talking about a WCF client. And the described behavior that I fall back to NTLM and it works is persistent over a server reboot. I can even reproduce this in two totally independent environments. Also yes, probably the quoted answer is wrong or at least incomplete. – Lux Dec 06 '16 at 05:13
  • 1) What is the actual default behavior? 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. Ref: https://msdn.microsoft.com/en-us/library/ms733130(v=vs.110).aspx – T-Heron Dec 07 '16 at 04:05
  • 2) Why is http/myhostname not selected as the default SPN as it should due to RFC4559? 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 your scenario #2 where you set the identity to host/myhostname. Makes sense? – T-Heron Dec 07 '16 at 04:05
  • I structured my last two responses specifically to target your questions. I didn't place them into an *Answer* format just in case you wanted more clarity on the responses. Let me know if that's the case, and I'll research more, or let me know if these do in fact satisfactorily answer your question and I'll place them into an *Answer* so others may benefit from your question. – T-Heron Dec 07 '16 at 20:45
  • @THeron thanks for your response. There msdn reference is really interesting. I just absolutely don't understand why I have a different behavior between #1 and #2 if `host/myhostname` is the default SPN. Why does it fall back to NTLM in #2 and throws and exception in #1. I would expect exactly the opposite: If I specify the SPN it should never fall back to NTLM, but if i don't specify the identity it may fall back to NTLM. However; if you write it out as an answer I will accept if nothing with more details comes the next few days. – Lux Dec 07 '16 at 21:15
  • 1
    Thanks Lux. Before I write it out as an answer, let us discuss in a few more comments in case anyone else is reading this and wants to chime in. The differences in behavior you noted between #1 and #2 is very interesting. 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. Kerberos *really* wants fully-qualified DNS names (your examples, such as host/myhostname, is a "short" name). This will be revealing: https://blogs.iis.net/brian-murphy-booth/the-biggest-mistake-serviceprincipalname-s – T-Heron Dec 07 '16 at 21:24
  • The point about the different behavior between #1 and #2 if host/myhostname is the default SPN, is noted. There's something odd going on in the test test environment for sure. – T-Heron Dec 07 '16 at 21:31
  • @THeron Thanks for the link, that was the missing part for the puzzle for me. 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. – Lux Dec 08 '16 at 10:35
  • 1
    Great. Thanks for commenting back on this Lux. I'll put the resolution of this into the form of an Answer so that it may help others when searching for the same or similar question. – T-Heron Dec 08 '16 at 12:32

1 Answers1

4

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

T-Heron
  • 5,385
  • 7
  • 26
  • 52