Tuesday, September 25, 2012

Calling Web Services Using BasicAuth From .NET

At work I have to consume lots of web services from all over the place. They come in many flavors: .NET, Java, etc.

When calling Java Web Services written in WebSphere from .NET using BasicAuth (username and password), sometimes the credentials are not asked from the host and the return code is a 401:

Web Exception

The best way to fix this annoying problem is to create a partial class with the same name as the one generated by WSDL.exe and override the GetWebRequest(Uri uri) function.

Creating a Web Service Client:

WSDL.exe

Creating partial class with overridden method: 

public partial class Service
{
    public string Username { get; set; }
    public string Password { get; set; }

    private void setBasicAuthHeader(WebRequest req)
    {
        string authInfo = Username + ":" + Password;
        authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
        req.Headers["Authorization"] = "Basic " + authInfo;
    }

    protected override WebRequest GetWebRequest(Uri uri)
    {
        this.Credentials = new NetworkCredential(Username, Password);
        WebRequest request = base.GetWebRequest(uri);
        setBasicAuthHeader(request);
        return request;
    }
}

The code above will override the GetWebRequest method by adding an "Authorization" header containing the username and password. WebSphere looks for this header on basic authorization. This should get rid of the 401 return code.

Calling the Web Service:

void CallService()
{
    Service service = new Service();

    service.Username = "username";
    service.Password = "password";

    Result result = service.GetData();
}

And this is all there is to it. Now you can call any web service that accepts basic auth.