Access the underlying Request(WebRequest or HTTPRequest) object in WCF for Digest PreAuthentication

790 Views Asked by At

We are exposing the Entity objects through WCF Services. To retrieve the entities we make several requests through WCF, close to a 100 or more. We recently switched to Digest Authentication and noticing that every single server request is issuing a 401. This creating twice as much load on the server and since we have very large "posts", this will create additional traffic lag. The goal is to have only a single Challenge(401) from the server and the rest of the requests should include the Auth header so the server doesn't issue a 401. Since Digest is a challenge based protocol with an expiring nonce, even though we may not fully eliminate the 401's but at least avoid them for every request. Since we control both server and client we want send the Digest Auth header included on every request. There is a Pre-Authenticate property in .NET 2.0 webservices Style Web Reference Proxy/Client(that inherits SOAPHttpClientProtocol) that allows the Auth header to be included with the request, but with a WCF Services Web Reference client(that uses ChannelFactory) there isn't. There is a clear difference in the Request/Response traffic when this property is set and when it isn't. Since this is Digest Authentication(NOT Basic) I cannot add the Auth header manually during BeginRequest with a ClientMessageInspector.

    NetworkCredential creds = new NetworkCredential("username", "pass", "domain");

    //using .NET 2.0 "Web Reference" Style client that uses inherits SoapHttpClientProtocol:
    webReferenceClient = new Service1();
    webReferenceClient.Credentials = creds;
    //**Pre Authenticate **
    webReferenceClient.PreAuthenticate = true;
    string resp1 = "";
    for (int i = 0; i < 3;i++) 
        resp1 = resp1 + webReferenceClient.SayHello("jack");

    //using WCF "Service Reference" Client that uses ChannelFactory
    serviceReferenceClient = new Service1Client();

    serviceReferenceClient.ClientCredentials.HttpDigest.ClientCredential = creds;
    serviceReferenceClient.ClientCredentials.HttpDigest.AllowedImpersonationLevel =          TokenImpersonationLevel.Impersonation;

    string resp="";
    for (var i = 0; i < 3;i++) 
        resp = resp + serviceReferenceClient.SayHello("jack");

Fiddler trace with .NET 2.0 Style Web Reference Client, with Preauthenticate set. Notice that there is only one 401 and rest of the requests have Auth header.

PreAuthenticate with .net2.0 style web reference

Trace with WCF Style Service reference Client. Every single request generated a 401 from the server:

Authenticate Every Singe request

I see two options:

  1. Switch our Client code to use .NET 2.0 style Web reference Client, this will be a big move since we are doing some custom Fault handling.
  2. Find a way to get to the WebRequest or the HTTPRequest object of the WCF ChannelFactory and set the PreAuthenticate Property. How to get to the actual WebRequest object??

Are there any other options??

0

There are 0 best solutions below