I have a requirement to secure a streamed WCF net.tcp service endpoint using WIF. It should authenticate incoming calls against our token server. The service is streamed because it is designed to transfer large amounts of data n stuff.
This appears to be impossible. And if I can't get around the catch, my Christmas will be ruined and I'll drink myself to death in a gutter while merry shoppers step over my slowly cooling body. Totes serious, you guys.
Why is this impossible? Here's the Catch-22.
On the client, I need to create a channel with the GenericXmlSecurityToken I get from our token server. No problemo.
// people around here hate the Framework Design Guidelines. var token = Authentication.Current._Token; var service = base.ChannelFactory.CreateChannelWithIssuedToken(token); return service.Derp();
Did I say "no problemo"? Problemo. In fact,
NullReferenceException style problemo.
"Bro, " I asked the Framework, "do you even null check?" The Framework was silent, so I disassembled and found that
((IChannel)(object)tChannel). GetProperty<ChannelParameterCollection>(). Add(federatedClientCredentialsParameter);
was the source of the exception, and that the
GetProperty call was returning
null. So, WTF? Turns out that if I turn on Message security and set the client credential type to
IssuedToken then this property now exists in the
ClientFactory (protip: There is no "SetProperty" equivalent in IChannel, the bastard).
<binding name="OMGWTFLOL22" transferMode="Streamed" > <security mode="Message"> <message clientCredentialType="IssuedToken"/> </security> </binding>
Sweet. No more NREs. However, now my client is faulted at birth (still love him, tho). Digging through WCF diagnostics (protip: make your worst enemies do this after crushing them and driving them before you but right before enjoying the lamentations of their women and children), I see it's because of a security mismatch between the server and client.
The requested upgrade is not supported by 'net.tcp://localhost:49627/MyService'. This could be due to mismatched bindings (for example security enabled on the client and not on the server).
Checking the host's diags (again: crush, drive, read logs, enjoy lamentations), I see this is true
Protocol Type application/ssl-tls was sent to a service that does not support that type of upgrade.
"Well, self," I says, "I'll just turn on Message security on the host!" And I do. If you want to know what it looks like, it's an exact copy of the client config. Look up.
The binding ('NetTcpBinding','http://tempuri.org/') supports streaming which cannot be configured together with message level security. Consider choosing a different transfer mode or choosing the transport level security.
So, my host cannot be both streamed and secured via tokens. Catch-22.
tl;dr: How can I secure a streamed net.tcp WCF endpoint using WIF???