Vladimir Georgiev
Vladimir Georgiev

Reputation: 631

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

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 ?

Upvotes: 24

Views: 57451

Answers (5)

T. Kruger
T. Kruger

Reputation: 91

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");

Upvotes: 6

Gerard Jaryczewski
Gerard Jaryczewski

Reputation: 1062

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";

Upvotes: 7

Ladislav Mrnka
Ladislav Mrnka

Reputation: 364399

Is Basic authentication configured in configuration file? Do you need to pass only credentials or do you also need secured transport (HTTPS)?

First you need to set up binding to support Basic authentication

Setup for HTTP binding:

<bindings>
  <basicHttpBinding>
    <binding name="BasicAuth">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Basic" />
      </security>
    </binding>
  </basicHttpBinding>
</bindings>

Setup for HTTPS binding:

<bindings>
  <basicHttpBinding>
    <binding name="BasicAuthSecured">
      <security mode="Transport">
        <transport clientCredentialType="Basic" />
      </security>
    </binding>
  </basicHttpBinding>
</bindings>

Client endpoint has to use defined configuration like:

<client>
  <endpoint address="..." 
            name="..." 
            binding="basicHttpBinding" 
            bindingConfiguration="BasicAuth" 
            contract="..."  />
</client>

Then you have to pass credentials to the proxy:

proxy = new MyServiceClient();
proxy.ClientCredentials.UserName.UserName = "...";
proxy.ClientCredentials.UserName.Password = "...";

Upvotes: 28

Jagmag
Jagmag

Reputation: 10366

I would say it is likely to depend on how the web service expects you to pass the information. After all, you are only the consumer.

Having said that, it is common is web services to have the userid and password passed in the SOAP Header.

You can refer to this link for a sample implementation of this scenario

Sample Soap Message

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <AUTHHEADER xmlns="http://tempuri.org/">
      <USERNAME>string</USERNAME>
      <PASSWORD>string</PASSWORD>
    </AUTHHEADER>
  </soap:Header>
  <soap:Body>
    <SENSITIVEDATA xmlns="http://tempuri.org/" />
  </soap:Body>
</soap:Envelope>

Upvotes: -1

Peladao
Peladao

Reputation: 4090

This should cover it: http://msdn.microsoft.com/en-us/library/ms733775.aspx (See the Client section)

Upvotes: -1

Related Questions