How do I programmatically specify HTTPS for BasicHttpBinding?

16,898

You should NOT use the BasicHttpBinding, but BasicHttpsBinding. It will solve the problem I guess.

Share:
16,898
Reuben
Author by

Reuben

Updated on June 04, 2022

Comments

  • Reuben
    Reuben almost 2 years

    I'm trying to consume a web service in .NET 4 (Visual Studio 2010) that requires HTTPS and is authenticated with a client certificate. Currently, I'm writing a console program, just to prove the concept, but I'm having trouble with having the program recognise that it should be using https. At least that is what the error suggests:

    An error occurred while making the HTTP request to https://. This could be due to the fact that the server certificate is not configured properly with HTTP.SYS in the HTTPS case. This could also be cause by a mismatch of the security binding between the client and the server.

    Here's the sample code I am using :

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                BasicHttpBinding binding = new BasicHttpBinding();
                binding.Security.Mode = BasicHttpSecurityMode.Transport;
                binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
    
                Uri baseAddress = new Uri("https://<host>:<port>/<endpoint>");
    
                var certificate = new X509Certificate2("<localpath to certificate>.p12", "<password>");
                EndpointAddress endpointAddress = new EndpointAddress(baseAddress);
    
                ChannelFactory<LinePortType> factory = new ChannelFactory<LinePortType>(binding, endpointAddress);
                factory.Credentials.ClientCertificate.Certificate = certificate;
                LinePortType proxy = factory.CreateChannel();
    
    
                var header = new ctSoapHeaderMsg();
                var response = new object();
                var request = new PerformServiceRequest(header, "<string>");
                var responseCode = proxy.PerformService(request);
    
                Console.WriteLine("Response Code :" + responseCode.ToString());
                Console.WriteLine("Response :" + response.ToString());
    
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception.Message);
            }
    
            Console.ReadLine(); // Pause
        }
    }
    

    I've replaced a few of the sensitive strings with placeholders.

    It's entirely possibly that the issue may be with me not being able to configure the certificate properly. Eventually, I hope to have this loaded from a local certificate store, so I don't have to specify the password in the code or configuration.

    The LinePortType is a Service Reference based on a local WSDL. Because the WSDL was for a production environment, I'm changing the endpoint to reference a UAT environment, instead.


    On the recommendation from srsyogesh, I've updated to use WSHttpBinding, but I'm still getting the same error.

    The code inside the try is now looking like:

    var binding = new WSHttpBinding();
    binding.Security.Mode = SecurityMode.Transport;
    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
    
    var baseAddress = new Uri("https://<host>:<port>/<endpoint>");
    var endpointAddress = new EndpointAddress(baseAddress);
    
    var client = new LinePortTypeClient(binding, endpointAddress);
    
    client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindByIssuerName, "<issuername>");
    
    var header = new ctSoapHeaderMsg();
    var response = new object();
    var responseCode = client.PerformTelstraSQ(ref header, "<string>", out response);
    
    Console.WriteLine("Response Code :" + responseCode);
    Console.WriteLine("Response :" + response);
    
  • Reuben
    Reuben almost 11 years
    WSHttpBinding seems to be for hosting a web service, rather than connecting to an existing web service. Could you elaborate with an example of how WSHttpBinding would be used?
  • srsyogesh
    srsyogesh almost 11 years
    msdn.microsoft.com/en-us/library/ms731074.aspx , you can find the information about transport security with certificate authentication which you are trying . I am trying out a sample , once succeeded will post you the same . Also are you able to download the metadata (client config file from the wcf service), will it be possible for you to share it ?
  • Reuben
    Reuben almost 11 years
    The service is a web service, soap based, so all I have to go on is the WSDL that they have provided. Unfortunately, I'm unable to share it. I actually have successful communications with the service in PHP. I'm trying to work out how it is done in .NET.
  • srsyogesh
    srsyogesh almost 11 years
    I am not sure because without wsdl or client config given , it is very difficult to find the problem . Also can u check whether the solution given in social.msdn.microsoft.com/forums/en-US/wcf/thread/… and blogs.msdn.com/b/james_osbornes_blog/archive/2010/12/10/… help you.
  • Reuben
    Reuben almost 11 years
    I can't give you access to the client config, because I don't have access to it. I don't believe there is anything relevant in the WSDL to send the message. The only thing that would be is any defined end points, but I'm specifically setting a different end point, and I can tell that is being picked up correctly, because the error message states it.
  • Reuben
    Reuben almost 11 years
    The first link is about connecting to IIS with Windows Credentials. This is not what I am trying to do. The second link is about setting up a server / producer, which is also something that I am not trying to do.
  • Reuben
    Reuben almost 11 years
    I'm fairly certain a client using BasicHttpBinding can connect using HTTPS, by specifying binding.Security.Mode = BasicHttpSecurityMode.Transport; as per original code.
  • WiSeeker
    WiSeeker almost 8 years
    @Reuben +1; your comment of binding.Security.Mode = BasicHttpSecurityMode.Transport; should really be an answer and it should be accepted as valid answer.
  • Reuben
    Reuben over 7 years
    If only .NET 4.5 was available back then.