Question

Does WCF 4.0 have an analog class/module/whatever to WCF REST Starter Kit's RequestInterceptor?

Was it helpful?

Solution

There isn't anything which maps 1-1 to it, but you can use an IDispatchMessageInspector from WCF core to implement most of the scenarios for which the RequestInspector would do. The post at http://blogs.msdn.com/b/carlosfigueira/archive/2011/04/19/wcf-extensibility-message-inspectors.aspx has some detailed information about the message inspectors.

OTHER TIPS

I'm back with an update.

I happen to value simplicity in code and after successfully solving this issue, I can't say I prefer it any more than the Query String method. Dropping a single call into each service endpoint that calls an AuthN method alongside the AuthZ method seems easier than some might believe.

Anyway, enough of the opinions...on to the solution. The solution is right under our eyes on Stackoverflow at this link but not well described in our context...so I will give credit to "user634119" for the sample code found here: Headers in OperationContext

First, we need to add a serviceBehavior to our web.config file:

<behaviors>
  <serviceBehaviors>
    <behavior>
      <serviceAuthenticationManager serviceAuthenticationManagerType="WCF.BasicAuthorization, WCF"></serviceAuthenticationManager>
      <serviceAuthorization impersonateCallerForAllOperations="false" principalPermissionMode="Custom" serviceAuthorizationManagerType="WCF.BasicAuthentication, WCF">
      </serviceAuthorization>
    </behavior>
  </serviceBehaviors>
</behaviors>

Next make a class (called BasicAuthorization as referenced in the serviceBehaviors block above):

//Authorize the call against the URI resource being requested...
public class BasicAuthorization : ServiceAuthorizationManager
{
    public override bool CheckAccess(OperationContext operationContext, 
    ref Message message)
    {
        //some code
    }
}

Next make an Authentication class:

// Authenticate the header signature as described in my previous post
public class BasicAuthentication : ServiceAuthenticationManager
{
    public override ReadOnlyCollection<IAuthorizationPolicy> Authenticate(
        ReadOnlyCollection<IAuthorizationPolicy> authPolicy, Uri listenUri, 
        ref Message message)
    {
        //some code
    }
}

In the Authenticate method, use HttpRequestMessageProperty to pull the request header details out and perform the same 3 steps described in my first reply.

Eduardo, you asked: @carlosfigueira: Can I use it to implement an authentication subsystem?

I am working on that same issue and have at least one solution (described below) for you and an upcoming Authorization Header-based one (which I beleive is the one you are thinking of "intercepting").

The simplest way to secure a WCF 4 REST WebHttp programming model-based endpoint is this:

  1. Issue a Shared Secret Key and an API Key to each client to use as credentials. The API key is really the same as a user name.
  2. Run all endspoints over SSL to ensure you always have channel/message/data security
  3. Require the clients to use the Shared Secret to generate a HMAC-SHA1 (or equiv) hash signature string that includes a timestamp and their API Key.
  4. Require the client to pass all 3 of these as query strings parameters in every request:
  5. On your service side, implement an Authentication method that takes all 3 strings and then:
    • Looks up the API key and returns the client's shared secret that you have in a DB or somewhere else.
    • Compare the timestamp against DateTime.Now to make sure the request isn't more than 15 mins old to fend off replay attacks.
    • Using those 3 strings, recreate the signature string and compare yours to the one passed in by the client.
    • If they match, the requestor is authentic.

Now, the better way to do this is by using the HTTP Authorization Request Header to store those 3 strings and to have a global interceptor-ish process watch all requests. This would prevent the potential for an exposed endpoint without an authentication block (well, at least its less likely perhaps).

Problem with using the query string to carry all this info is the query string has a 2k max length (which varies by client/browser) and the query string gets really hard to read when debugging...but just get used to it.

Some think a more sophisticated way to do this is a STS model where you require the client to pass these 3 authentication strings to an Security Token Service endpoint. The response message would pass back a session token which the client would pass in on each call in lieu of the 3 strings. It is true that for the client there is no need to generate an HMAC hash signature on each call, but the server side must still authenticate the token and the session concept fouls up the clean RESTful stateless behavior.

I will do my best to post code blocks that implement both the query string and the auth header methodologies.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top