如何拦截WCF .svc服务中对方法的所有调用?

时间:2011-09-20 10:49:55

标签: asp.net wcf

我有一个WCF服务,其中包含多个Web方法。我希望能够拦截所有方法的请求并查看IP地址。我宁愿不把逻辑放到每个被调用的web方法顶部的方法调用中,有没有办法从一个地方拦截对这些方法的所有调用?

如果它是一个页面,我会写一个基页对象,但我不确定是否在wcf调用中引发了事件?

4 个答案:

答案 0 :(得分:3)

WCF允许您实现添加到堆栈的拦截器。有关示例,请参阅此link。我不确定这是否允许您提取发件人IP,但我认为值得一试。

答案 1 :(得分:3)

您可以实现IDispatchMessageInspector并执行类似的操作。

public object AfterReceiveRequest(ref Message request, 
IClientChannel channel, InstanceContext instanceContext)
    {
        RemoteEndpointMessageProperty remoteEndpoint = request.Properties
    [RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;

        //remoteEndpoint.Address will give you the address.  

        return null;
    }

答案 2 :(得分:1)

您可以使用自定义行为,它们是WCF可扩展性功能的一部分。以下是更多信息:Extending WCF with Custom Behaviors

答案 3 :(得分:1)

ServiceAuthorizationManager有一种聪明的方法可以做到这一点,它比IDispatchMessageInspector的所有认真努力工作容易得多。

在WCF服务项目中创建一个类,如下所示:

public class MyServiceAuthorizationManager : ServiceAuthorizationManager
{
  protected override bool CheckAccessCore(OperationContext operationContext)
  {
    string classMethod = operationContext.RequestContext.RequestMessage.Headers.Action;
    if (classMethod.Contains("/transfer/Get"))
    {
      return true; // because someone is simply updating a client service reference
    }
    Console.WriteLine("Class Method Call: {0}",classMethod);
    // do something with operationContext here as you need to inspect stuff
    // return true if you want this class method call to succeed and go through
    // return false if you want this class method to fail on the client
    return true;
  }
}

然后,在您的服务中,在host.Open()来电之前,将链接添加到MyServiceAuthorizationManager

ServiceHost host = new ServiceHost(typeof(MyProject.Service1));
host.Authorization.ServiceAuthorizationManager = new MyServiceAuthorizationManager();
host.Open();

现在,当您测试客户端连接时,您会注意到控制台输出了调用的类方法。您还可以处理operationContext对象中的所有内容。

我使用它的一种方法是进行安全标头检查。在我的客户端,我添加了一个标题。然后,在服务中,在此CheckAccessCore()调用中,我验证此自定义标头是否存在。如果它没有,那么我返回false。这是保护黑客的另一层保护,并且对于命名管道配置中的有限安全性也很有用。如果您还希望这样做,请click here了解有关如何添加自动在每个客户端对该服务进行方法调用时发送的自定义标头的详细信息。

请注意,在所有这些中,我不必混淆行为,声明,听众或消息发送。我也不需要编辑我的WCF配置。

请注意上面/transfer/Get的字符串检查。如果您像我一样将标头检查作为安全机制进行,这一点非常重要。如果您没有这个条件并且返回true,那么您的WCF客户端IDE无法更新其ServiceReference,因为IDE不知道该额外标头(如果您'重新添加自定义标头,而不是在WCF客户端的app.config中指定该标头。否则,您将收到错误The URI prefix is not recognized