Which Client Credential Does TransportWithMessageCredential Use?
I'm trying to use a Certificate credential with security mode TransportWithMessageCredential. Certificate credentials were working with transport security but now my clients can't connect. Why isn't this working?
This one is fairly quick to diagnose if you look at what your service is telling you. I've set up a service with the WSHttpBinding and the security mode set to TransportWithMessageCredential. What's probably gone wrong is that the configuration is setting the transport client credential type to Certificate.
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
Let's look at what the service metadata says that is doing.
<wsHttpBinding>
<binding name="WSHttpBinding_Service" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
Hmm, the transport client credential type seems to be ignoring the setting and the message client credential type is Windows.
What's going on is that TransportWithMessageCredential only uses the message security credentials. The transport (HTTPS in this case) is locked to anonymous authentication and the message credentials are using Windows because that's the default if you don't change any of the settings. The mismatch between Windows and Certificate credentials are why the clients are failing. We can fix this by changing the client credential type line to set the message security credentials instead.
binding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
Now, the security block in the metadata gives us exactly what we want.
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
Next time: Impersonating with Windows Security