Open
Description
On Windows, it uses NegotiateStream to establish the connection. As part of that, we pass a target name to NegotiateStream.AuthenticateAsClientAsync which is used to get a Kerberos ticket or decide to use NTLM. There's shared code which implicitly uses the hostname from the endpoint address Uri, but with UDS there is no hostname. This results in a bad target name being used (it ends up using host/
) and authentication failing.
Workaround:
Construct you EndpointAddress like this:
var endpointAddress = new EndpointAddress(new Uri("net.uds://" + servicePath), new SpnEndpointIdentity("host/localhost"));
This will override the implicit target name to be host/localhost
and the NegotiateStream authentication will succeed.
A few options to fix this.
- On the CreateChannel code path, we could create a new Uri from the passed in Uri which has the hostname portion populated with localhost if it's currently empty.
- On the CreateChannel code path, we could add an SpnEndpointIdentity("host/localhost") to the EndpointAddress if there isn't currently an identity.
- In the code which calculates the target name, treat an empty hostname as the empty string target name. So if the hostname is non-empty, generate the target name
host/localhost
, but if the hostname is empty, generate the target name String.Empty. I have verified String.Empty successfully authenticates.