A little while ago I added username authentication to some WCF services we have. This used message level authentication to hold the username and password, which required an x509 certificate to be used to secure the transport (as we’re sending passwords over it). One flaw was that message level security does not work with streamed bindings (as the message security, which comes before the message hits the service, depends on the message body, so if it’s streamed you can’t establish security until the stream has finished). So a couple of our services require streamed bindings as they involve sending massive attachments to the WCF service (forget for the moment the dubiousness of sending massive attachments to a WCF service). This caveat was decided to be acceptable as all the other services were secured.
More recently it has become apparent that these streamed binding services also require security… oh dear! So it actually turns out it’s not that difficult, but oddly enough I couldn’t really find any directly related material on the interweb detailing this solution, so here it is.
For any streamed binding that needs to be secured using username message credentials set the security mode to mixed mode (TransportWithMessageCredential), the transport security to certificate and the message credential to username:
binding.Security.Mode = SecurityMode.TransportWithMessageCredential;
binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Certificate; binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
This is a slightly different configuration than username based message security, and the caveat about streamed bindings does not apply. I think the difference is that instead of all security being taken care of at the message level only the credential passing is at the message level, other aspects of security are taken care of at the transport level. Therefore you no longer need the whole message body to establish security as this is taken care of at the transport layer. The disadvantage of using this security mode is that the transport is now essential for establishing security, so over multiple-hop connections the security wont work (I’m guessing). Therefore for non-streamed connections we’re going to stick to message security, degrading to mixed-mode security for streamed bindings.
Why does WCF security have to be so complicated? and how come I keep on getting lumbered with it? 😉