Username message credentials over streamed binding

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? 😉

Advertisements

About Alex McMahon

I am a software developer, interested in .net, agile, alt.net. I've previously specialised with .net 3.0 technologies like WCF, whereas now I am trying to specialise in agile development and best practice and patterns. I am obsessed with looking at the latest technologies, tools, and methods, and trying them out. I am currently employed by Rockwell Collins in the UK.
This entry was posted in development, Security, wcf. Bookmark the permalink.

2 Responses to Username message credentials over streamed binding

  1. Peter says:

    I tried that, I’ve got two end points setup, one TCP and one HTTP, copied my config from another one that I know is working with all the same settings, certificates and the ASP.NET Membership Provider, changed the mode from Message to TransportWithMessageCredential, TCP worked straight away, change the HTTP to basicHttp instead of wsHttp of course, change the security mode and it failed with “InnerException = {“The underlying connection was closed: An unexpected error occurred on a send.”}”

    TCP Worked 🙂 HTTP doesn’t, any help would be greatly appreciated.

  2. Alex McMahon says:

    @Peter:
    I only set it up with TCP, so I’m not entirely sure. My first instinct is that there was probably a more useful exception in the WCF Service trace, I’d turn service tracing on (client and server side), and then look at the logs (don’t forget to use Microsoft’s Service Trace Viewer application).

    As far as I’m aware there’s no reason it shouldn’t work with basicHttp – maybe it’s worth double checking your WCF configuration on both sides, also remember that different bindings have different defaults, so maybe part of the basicHttpBinding has a default configuration value on one end that differs from the explicit value on the other.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s