Authenticated Web Services in .NET

Sometimes I get the feeling that I’m doing something a little too out there. This usually occurs when something that I thought would be simple and widely implemented … isn’t. This was my thinking as I dived into the world of authenticated .NET web services.

My use case is simply to invoke a web service with user-provided credentials. If the credentials fail, prompt the user again, displaying the reason they could not be logged in.

The first part is straightforward. Just set the Credentials property on the SoapHttpClientProtocol instance and you’re away.

However if you want to present the user with a login dialog when credentials are required (pull, not push), it is definitely not straightforward. I was expecting something like Java’s authentication callback but I couldn’t find anything remotely like it. There may be other ways, but the way I did it was to:

  1. Create a class that implements IAuthenticationModule and decorates another instance.
  2. Add an event to the class (I called it AuthenticationRequired and make it fire from the Authenticate method before you delegate to the wrapped instance. The event you create needs to take custom arguments so the event handlers can modify and return the authentication details.
  3. Use the System.Net.AuthenicationManager.RegisteredModules enumeration to find the module registered for the authentication type you’re using (e.g. Basic, Digest), wrap it with an instance of your event driven class, and replace it using the Register method.
  4. Register an event handler with your wrapped instance. The event handler can display a dialog, and update or replace the ICredentials instance you passed in the AuthenticationRequestEventArgs.
    Caution! Remember that Windows forms is not thread safe: if you do need to do some GUI work, make sure you use the Invoke and InvokeRequired methods on Form to avoid synchronization issues.
  5. Make sure your SoapHttpProtocolClient instance has the UseDefaultCredentials set to true, otherwise the AuthenticationModules won’t be called. PreAuthenticate should be true as well to save a request if you know that authentication will be required.

That’s it … well, almost. This will allow you to ask for Credentials once per call. If the user enters invalid credentials, the request will fail. Not optimal. To make .NET ask you again, you have to repeat the request.

You can either do that each time you make a request, or you can create a method that takes a delegate as a parameter and does the repetition … or you could use a dynamic proxy. For me, laziness appeals, so I used Castle’s dynamic proxy implementation. This might be the subject of another post though …

No Responses to “Authenticated Web Services in .NET”

  1. Nick Says:

    So I take it you didn’t use SWT, then?

  2. jt Says:

    No … the whole Java GUI thing just didn’t thrill me, no matter how much I like Eclipse. For that matter, I could have used the Eclipse runtime. I’m committed now, I think, though there’s not much client side actually accomplished.

    I could switch to Hessian as the transport protocol - there’s a C# implementation of that. My gut feeling is still that a Java GUI will take longer to implement than a .NET one, hiccups notwithstanding. There a large amount of personal comfort in that estimation though.

    Time will tell I suppose.