Calling a web service that requires basic http authentication from wcf client

Viewed 51091

I have a wsdl from a web service, I generated the wcf proxy. No problem.

But I can not get my head around how to pass the user name and password. The webservice requires basic authentication - only username and password.

Any help ?

5 Answers

For people (A) coming to this answer in context of .NET Core projects and (B) interested in changes in code, not in XML files:

  1. Use dotnet-svcutil to scaffold code with WSDL.
  2. Update GetBindingForEndpoint in Reference.cs method to enable Basic Authentication in WCF client.
  3. Set login and password when using the client instance.

Example codes:

private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration)
{
    if ((endpointConfiguration == EndpointConfiguration.YourService))
    {
        System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding();
        result.MaxBufferSize = int.MaxValue;
        result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
        result.MaxReceivedMessageSize = int.MaxValue;
        result.AllowCookies = true;

        // Set Basic Authentication with HTTP protocol (for HTTPS you need "Transport"):
        result.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
        result.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;

        return result;
    }
    throw new System.InvalidOperationException(string.Format("Could not find endpoint with name \'{0}\'.", endpointConfiguration));
}
var client = new YourServiceClient();
client.ClientCredentials.UserName.UserName = "yourservicelogin";
client.ClientCredentials.UserName.Password = "yourservicepassword";

Refering to the answer of @Gerard Jaryczewski in .NET Core projects, you can also use the following extension method as editing the Reference.cs can be a challenge because after each update of the Reference.cs the changes will be overwritten.

public static class BasicAuthenticationExtension
{
    public static void SetBasicAuthentication<T>(this ClientBase<T> client, string userName, string password) where T : class
    {
        if (client == null) throw new ArgumentNullException(nameof(client));
        if (client.Endpoint == null || client.Endpoint.Binding == null) throw new Exception("The specified client has no binding defined!");

        if (client.Endpoint.Binding is BasicHttpsBinding httpsBinding)
        {
            httpsBinding.Security.Mode = BasicHttpsSecurityMode.Transport;
            httpsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
        }
        else if (client.Endpoint.Binding is BasicHttpBinding httpBinding)
        {
            httpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
            httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
        }
        else
        {
            throw new NotSupportedException("The specified client has a binding defined which is not supporting HTTP basic authentication!");
        }

        client.ClientCredentials.UserName.UserName = userName;
        client.ClientCredentials.UserName.Password = password;
    }
}

You can then just use it like this:

var client = new MyServiceClient();
client.SetBasicAuthentication("myUserName", "myPassword");
Related