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 with96 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 lettersNTLMSSP
. - Response with
WWW-Authenticate: Negotiate XXX
where XXX are 270 BASE64 encoded bytes. The first bytes are the ASCII lettersNTLMSSP
. 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:
- If the default identity is
host/myhostname
, - it should make no difference to manually specify the identity to
host/myhostname
, - but there is a difference
- so this can't be default identity.
So my questions are
- What is the actual default behavior, and
- why is
http/myhostname
not selected as the default SPN as it should due to RFC4559?
And/or did I understood something completely wrong?