I'm managing a shared auth cookie when making WCF service calls via this methodology outlined under the header "Centralized cookie management" located here: http://megakemp.com/2009/02/06/managing-shared-cookies-in-wcf/
I've set up a custom IClientMessageInspector
, IEndpointBehavior
, BehaviorExtensionElement
, the works. My endpoint behavior adds a message inspector as follows:
public class MyEndpointBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
// yuck.. Wish I had an instance of MyClientMessageInspector
// (which has the auth cookie already) so I could just inject that
// instance here instead of creating a new instance
clientRuntime.MessageInspectors.Add(new MyClientMessageInspector());
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
It all works flawlessly, but this solution breaks down when you want to share cookies over multiple clients. Because the ApplyDispatchBehavior()
method creates a new instance, any other client wouldn't get that message inspector instance, and thus, the auth ticket.
So then I thought of trying to create a custom constructor where I could inject the instance like so:
MyEndpointBehavior(MyClientMessageInspector msgInspector) { ... }
But, WCF needs parameter-less constructors. Weeding through the internets, WCF has hooks to allow for dependency injection, creating an IInstanceProvider
, IServiceBehavior
, etc. But I don't think that's what I'm looking for here.
Can anyone help guide me in the right direction?
I liked the answers provided by @carlosfigueira and @drew, but I ultimately came up with a slightly different approach. I opted to configure my IEndpointBehavior PROGRAMMATICALLY, vs via config. Made things much simpler. I changed my endpoint behavior to store my client message inspector as follows:
public class MyEndpointBehavior : IEndpointBehavior
{
private MyClientMessageInspector_myClientMessageInspector;
public MyClientMessageInspector MyClientMessageInspector
{
get
{
if (_myClientMessageInspector == null)
{
_myClientMessageInspector = new MyClientMessageInspector();
}
return _myClientMessageInspector;
}
}
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(MyClientMessageInspector);
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
Then I simply shared this behavior between clients, as follows:
var behavior = new MyEndpointBehavior();
client1.Endpoint.Behaviors.Add(behavior);
client2.Endpoint.Behaviors.Add(behavior);
Now both clients will share the same auth cookie.