Basic Http authentication from .NET to PHP webservice

Today, I had a major problem that had a not-so-complex-but-rather-stupid solution so I thought it might be worth sharing since I only found online solutions that were rather old.

I have remote access to a PHP webservice, written using NuSOAP. I call the methods of this webservice from a .NET application. This is no problem at all and I can easily call most webservice methods from within .NET. But some of the methods require basic authentication and now the trouble begins.

One would think that it would be enough to just set the credentials for the webservice and make sure that it authenticates on every request. Like this:

MyPhpWebservice ws = new MyPhpWebservice();
ws.PreAuthenticate = true;
CredentialCache cache = new CredentialCache();
cache.Add(
   new Uri(ws.Url),
   "Basic", 
   new NetworkCredential(wsUsername, wsPassword)
);
ws.Credentials = cache;
ws.CallSomeFunctionThatNeedsAuth();

Alas, this did not work. In many places online, people say that .NET does not actually send the authentication details on the first request for some webservice function. If this was true, the solution would simply be:

ws.CallSomeFunctionThatNeedsAuth(); // Does not auth
ws.CallSomeFunctionThatNeedsAuth(); // Should auth now?

This did not work either. Other people in other places online say that one needs to manually add the authentication details to the HttpWebRequest header. But the Visual Studio auto-created MyPhpWebservice class does not expose its WebRequest object so it cannot be directly altered. However, we can override the method GetWebRequest for the webservice and that way manually add the authentication header. This took me a while to figure out but here is a simple solution:

class MyOverriddenPhpWebservice : MyPhpWebservice
{
    protected override System.Net.WebRequest GetWebRequest(Uri uri)
    {
        HttpWebRequest request;
        request = (HttpWebRequest)base.GetWebRequest(uri);

        if (PreAuthenticate)
        {
            NetworkCredential cred =
                Credentials.GetCredential(uri, "Basic");
            if (cred != null)
            {
                byte[] credBuffer = new UTF8Encoding().GetBytes(
                    cred.UserName + ":" + cred.Password);
                request.Headers["Authorization"] =
                    "Basic " + Convert.ToBase64String(credBuffer);
            }
        }
        return request;
    }
}

The code that I wrote in Listing 1 is now perfectly valid and all I need to do is exchange MyPhpWebservice with MyOverriddenPhpWebservice.

And the best part: It works :-)

3 comments

  1. Thanks! I spent a couple of days a while back looking for a solution. Kind of found the bits and pieces that are listed here, but didn’t have the knowledge to put them together. Just had to convert this to C++/CLI and voilà, my application works now.

  2. It’s not a problem in .net, your php code should be requesting basic authentication, if not, add this code:

    if (!isset($_SERVER[‘PHP_AUTH_USER’])) {
    header(‘WWW-Authenticate: Basic realm=”My Realm”‘);
    header(‘HTTP/1.0 401 Unauthorized’);
    exit;
    }

Leave a Reply to David Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.