WCF 跨多个客户端共享 IClientMessageInspector 实例
当通过位于此处的标题“集中 cookie 管理”下概述的方法进行 WCF 服务调用时,我正在管理共享身份验证 cookie:http://megakemp.com/2009/02/06/managing-shared-cookies-in-wcf/
我已经设置了自定义的 IClientMessageInspector
、IEndpointBehavior
、BehaviorExtensionElement
,有效。我的端点行为添加了一个消息检查器,如下所示:
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)
{
}
}
一切都完美工作,但是当您想要在多个客户端上共享 cookie 时,此解决方案就会崩溃。由于 ApplyDispatchBehavior()
方法创建了一个新实例,因此任何其他客户端都无法获取该消息检查器实例,因此也无法获取身份验证票证。
因此,我想到尝试创建一个自定义构造函数,在其中可以注入实例,如下所示:
MyEndpointBehavior(MyClientMessageInspector msgInspector) { ... }
但是,WCF 需要无参数构造函数。通过互联网进行筛选,WCF 具有允许依赖项注入、创建 IInstanceProvider
、IServiceBehavior
等的钩子。但我不认为这就是我在这里寻找的东西。
谁能帮助引导我走向正确的方向?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您只需扩展该概念,以便将 cookie 存储在消息检查器本身之外,以便消息检查器的所有实例共享相同的存储。
穷人的方法,只是开始,就是使用静态字段而不是实例字段。显然,如果您有多个线程,则需要在更新字段时提供并发性。从这里开始,如果您将其推断为 cookie 容器概念,然后确保与所有客户端共享同一个容器,您可以变得更加奇特。可以通过获取客户端通道的 ChannelParameterCollection 并向其添加属性来共享容器,然后您的行为在检查消息并从中提取 cookie 时查找该属性。这看起来有点像这样:
应用程序逻辑
消息检查器逻辑
You need only extend the concept so that you store the cookie outside of the message inspector itself so that all instances of the message inspector share the same storage.
The poor man's way, just to get started, would be to just use a static field instead of an instance field. Obviously if you have multiple threads you'll need to provide concurrency while updating the field. From there you can get even fancier if you extrapolate it out to a cookie container concept and then just make sure you share the same container with all clients. Sharing the container can be done by getting the
ChannelParameterCollection
for the client channel and adding property to it and then your behavior looks for that property while it's inspecting the mssage and pulling the cookies out of that. That would look a little something like this:App logic
Message inspector logic
你是对的, IInstanceProvider 对你的情况没有帮助 - 它仅用于提供服务实例。您的行为不需要无参数构造函数。您需要配置元素的无参数构造函数,并且此类可以使用某些依赖项注入类(见下文)来创建行为所需的适当检查器类。
You're correct, IInstanceProvider won't help in your case - it's used for providing service instances only. You don't need a parameterless constructor for your behavior. You need a paramterless constructor for the config element, and this class can use some dependency injection class (see below) to create the appropriate inspector class needed for the behavior.
我喜欢@carlosfigueira 和@drew 提供的答案,但我最终想出了一个稍微不同的方法。我选择以编程方式配置 IEndpointBehavior,而不是通过配置。让事情变得简单多了。我更改了端点行为以存储客户端消息检查器,如下所示:
然后我只是在客户端之间共享此行为,如下所示:
现在两个客户端将共享相同的身份验证 cookie。
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:
Then I simply shared this behavior between clients, as follows:
Now both clients will share the same auth cookie.