Exitos
Exitos

Reputation: 29720

How can I intercept all calls to methods in a WCF .svc service?

Ive got a WCF service which has multiple web methods in it. I want to be able to intercept the request on all methods and look at the Ip address. Id rather not put the logic into a method call at the top of each called web method is there a way to intercept all calls to these methods from one place?

If it was a page I would write a base page object but im nout sure if there are events raised on a wcf call?

Upvotes: 5

Views: 5145

Answers (4)

Volomike
Volomike

Reputation: 24886

There's a clever way to do this with the ServiceAuthorizationManager, and it's far easier than all the seriously hard work of the IDispatchMessageInspector.

Create a class in your WCF Service project like so:

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;
  }
}

Then, in your service, right before your host.Open() call, add the link to MyServiceAuthorizationManager.

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

Now when you test your client connections, you'll notice that the console outputs what class method was called. You can also work against all the stuff in the operationContext object.

One way I use this is for a security header check. In my client, I add a header. Then, in the service, in this CheckAccessCore() call, I verify that this custom header exists. If it doesn't, then I return false. This is one more layer of protection that keeps the hackers out, and is great for the limited security in Named Pipes configurations too. If you're wanting to also do that, then click here for more information on how to add custom headers that automatically get sent on every client's method call on the service.

And note, among all this, I didn't have to mess with behaviors, claims, listeners, or message dispatches. I also didn't need to edit my WCF Configuration.

Note the string check for /transfer/Get above. This is important if you're doing header checks as a security mechanism like I was. If you don't have that condition and return true, then your WCF client IDE can't update its ServiceReference because the IDE doesn't know about that extra header (if you're adding a custom header and not specifying that header in the WCF client's app.config). Otherwise, you'll get an error The URI prefix is not recognized.

Upvotes: 1

Hari Subramaniam
Hari Subramaniam

Reputation: 1876

You can implement IDispatchMessageInspector and do something like this.

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;
    }

Upvotes: 3

Dmitry Samuylov
Dmitry Samuylov

Reputation: 1564

You can use Custom Behaviors, they are part of WCF Extensibility features. Here's more information: Extending WCF with Custom Behaviors

Upvotes: 1

Dominik
Dominik

Reputation: 3362

WCF allows you to implement interceptors that are added to the stack. See this link for an example. I´m not sure whether this allows you the extract the senders IP but I think it´s worth a try.

Upvotes: 3

Related Questions