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:
I create the EndpointAddress
with the following code:
new EndpointAddress(new Uri(endpoint))
In this scenario the following is happening:
Authorization
header.WWW-Authenticate: Negotiate
.Authorization: Negotiate XXX
header. XXX
are 1584 BASE64 encoded bytes, starting with 96 130 6
. I can't find any readable ASCII inside it.Authorization: Negotiate XXX
header. XXX
are 126 BASE64 encoded bytes. I can't find any readable ASCII inside it.Authorization: Negotiate XXX
header. XXX
are 1527 BASE64 encoded bytes. I can't find any readable ASCII inside it.WWW-Authenticate: Negotiate XXX
header. XXX
are 113 BASE64 encoded bytes. I can't find any readable ASCII inside it.The target principal name is incorrect
.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:
Authorization
header.WWW-Authenticate: Negotiate
.Authorization: Negotiate XXX
where XXX are 40 BASE64 encoded bytes. The first bytes are the ASCII letters NTLMSSP
.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.Authorization: Negotiate XXX
, where XXX are 590 BASE64 encoded bytes. No ASCII letters this time tho.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.
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:
Authorization
header.WWW-Authenticate: Negotiate
.Authorization: Negotiate XXX
header. XXX are 1580 BASE64 encoded bytes. No ASCI signs.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:
host/myhostname
,host/myhostname
,So my questions are
http/myhostname
not selected as the default SPN as it should due to RFC4559?And/or did I understood something completely wrong?
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."