Basic authentification in a soap / webservice call

You have a webservice (based on a wsdl), which you have to call? The owner of the webservice has set basic authentification as security requirement. You have added the webservice via “Add Web Reference” in Visual Studio with the name “WebServiceName”. The generated class MyServiceClass is a derived class of SoapHttpClientProtocol out of namespace System.Web.Services.Protocols. You have no access to the via wsdl prompted definitions and classes.

Unfortunatly it is not sufficient to add the credentials in this way:

ICredentials creds;
creds = new NetworkCredential(username, password);
WebServiceName.MyServiceClass client = new WebServiceName.MyServiceClass();
client.Credentials = creds;
client.PreAuthenticate = true;

client.MyMethodCall();

Solution:

You have to add a new class file to your project, which contains the same namespace as MyServiceClass is a member, e.g. WebServiceNameExtended.cs. Next, you create a new dervied class of MyServiceClass in this file, e.g. MyServiceClassExtended. Into the class you insert a method called GetWebRequest(), which overrides the standard class of System.Net.
So, every Request, which is sent to the webservice will be changed and the request header will contain the credentials and will integrate Basic Authentification.

Example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net;
using System.Text;
using System.Web.Services.Protocols;

namespace WebServiceName
{
    public class MyServiceClassExtended : MyServiceClass
    {
        protected override WebRequest GetWebRequest(Uri address)
        {
            WebRequest request = (WebRequest)base.GetWebRequest(address);

            if (request.PreAuthenticate)
            {
                NetworkCredential networkCredentials = request.Credentials.GetCredential(address, "Basic ");
                if (networkCredentials != null)
                {
                    byte[] credentialBuffer = new UTF8Encoding().GetBytes(networkCredentials.UserName + ":" + networkCredentials.Password);
                    request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(credentialBuffer);
                }
                else
                {
                    throw new ApplicationException("No network credentials");
                }
            }

            return request;
        }
    }
}