As I mentioned a few posts ago, I’ve been spending some time with WSE 2.0. One of the cool things in the new WS-* specs is WS-SecureConversation. SecureConversation maintains the ability to enforce authentication and authorization at a per call basis, while lowering the runtime burden of actually performing a full authentication for each round trip call. I’m not going to go too far into details here, as there’s plenty of information on WS-SecureConversation available on the web.
The problem that I had with the Microsoft WSE 2.0 implementation of SecureConversation is that all of the Microsoft examples that I saw used policy files to set up the “Conversation.” This really works great out of the box, and allows two applications to set up a conversation with little more than wiring up some incredibly complicated XML configuration files. This conversation is enforced at the AppDomain level.
However, my application model required that the secure conversation take place at a “user” level from within the application, with the idea that the “client” application must be able to host more than one different user from within the AppDomain during the application’s lifetime. I performed “Action” level authorization by writing a custom server side filter that analyzed the BaseToken of the SecureContextToken, and that information combined with the “Action” from the SOAP header allowed me to decide whether or not the user was authorized to perform that specific Web Service call.
The problem with this model is related to the automatic conversation set up by WSE on the client side. If policy is used to enforce SecureConversation on the client, WSE caches the first SecureContextToken issued to it. WSE continues to use this token for the lifetime of the application (or until token expiration). So, if user “Bob” logs in, logs out, and then user “Alice” logs in, the client application will still assign Bob’s SecureContextToken to the message. This broke my server side authorization logic, as the filter looked at the incoming SecureContextToken to get the Username BaseToken.
Well, that makes sense, if you understand what is going on. It’s also relatively easy to fix. Instead of allowing WSE to manage SecureConversation through Policy as all of the examples show, you may manually implement SecureConversation in your client side proxy code. It’s not much code, and once you know what you are going for, it’s pretty straightforward.
The real problem that I ran into, however, is that while the documentation is fairly thorough, it mostly deals with a common use case or model, and when you stray from this, you’ll find yourself in the land of experimentation and ILDASM.
After building an end to end communications platform based on WSE, my team has since thrown it away. We are using a remoting based framework instead. More on this in a future post.