none
WCF Self Host Via Https Fails RRS feed

  • Question

  • So I am pretty stuck here. I've always been able to host WCF apps with no problem over http. I can setup https WCF apps in IIS. But when I'm trying to use a self hosted https wcf app this has been nothing but a nightmare. I am running both the client and self hosted service on the same computer. Also, the service opens each time I run it with no errors. It's reported state is open. When I try to connect with the client (which is activating the service via channel factories) it crashes with the SSL/TLS error as described below. I've been at this for about 2 days now and can't get it to work :(

    I have tried following several guides such as (but not limited to) the ones here: http://blogs.msdn.com/b/james_osbornes_blog/archive/2010/12/10/selfhosting-a-wcf-service-over-https.aspx as well as here: http://msdn.microsoft.com/en-us/library/ms733791.aspx. The first document I follow it to the letter and at the end when the author says "And that's it! now we can call the program and it will invoke the service" it doesn't. It gives me an error: "Could not establish trust relationship for the SSL/TLS secure channel".

    So I tried a slightly different approach upon coming on to the second article. I tried to use an existing certification already listed for my server (which is stored under personal certifcations). I copied the thumbprint and registered it with the port creating my own app id. That didn't work so I thought well lets try to force the client certificate thumbprint on both the service and the client by specifying the client credentials and looking it up via thumbprint like so:

    factory.Credentials.ClientCertificate.SetCertificate(System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine, System.Security.Cryptography.X509Certificates.StoreName.My,
                        System.Security.Cryptography.X509Certificates.X509FindType.FindByThumbprint, "f80e16f75e805b951e6099979f6dcea56bce3273");
    I still get the same results. What am I missing? Here is the code for both the service and the client.
    Client:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.ServiceModel;
    using HttpsSelfHost;
    namespace ConsoleApp4
    {
        class Program
        {
            static void Main(string[] args)
            {
                string address = "https://localhost:8007/HelloWorldSvc";
                WSHttpBinding binding = new WSHttpBinding();
                binding.Security.Mode = SecurityMode.Transport;
                binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
                try
                {
                    ChannelFactory<IHelloWorldSvc> factory = new ChannelFactory<IHelloWorldSvc>(binding, address);
                    factory.Credentials.ClientCertificate.SetCertificate(System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine, System.Security.Cryptography.X509Certificates.StoreName.My,
                        System.Security.Cryptography.X509Certificates.X509FindType.FindByThumbprint, "f80e16f75e805b951e6099979f6dcea56bce3273");
                    IHelloWorldSvc client = factory.CreateChannel();
                    Console.WriteLine("Invoking service.");
                    string str = client.HelloWorld();
                    Console.WriteLine("Returned: {0}", str);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
                Console.WriteLine("Press enter to quit.");
                Console.ReadLine();
            }
        }
    }


    Service:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.ServiceModel;
    namespace HttpsSelfHost
    {
        class Program
        {
            static void Main(string[] args)
            {
                string address = "https://localhost:8007/HelloWorldSvc";
                WSHttpBinding binding = new WSHttpBinding();
                binding.Security.Mode = SecurityMode.Transport;
                binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
                using (ServiceHost host = new ServiceHost(typeof(HelloWorldSvc)))
                {
                    host.AddServiceEndpoint(typeof(IHelloWorldSvc), binding, address);
                    host.Credentials.ClientCertificate.SetCertificate(System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine, System.Security.Cryptography.X509Certificates.StoreName.My,
                        System.Security.Cryptography.X509Certificates.X509FindType.FindByThumbprint, "f80e16f75e805b951e6099979f6dcea56bce3273");
                    host.Open();
                    Console.WriteLine("Host is: {0}. Press enter to close.", host.State);
                    Console.ReadLine();
                    host.Close();
                }
            }
        }
    }


    Wednesday, April 9, 2014 3:35 PM

Answers

  • I had tried that and it didn't work. But I found out the solution. The hash had to be uppercase apparently. Even though the server hash in mmc was lower case the client and server would not communicate unless I made the client certificate in uppercase. Just as a suggestion you might want to provide an example of that working in this article: http://msdn.microsoft.com/en-us/library/ms733791.aspx as an alternative for the FindBySubjectName("contoso.com") section. There is nothing that says in any article I can find that the hash has to be upper case. I found it by using a server callback on the client to see what certificate hash it was expecting.
    • Marked as answer by Ryan MVSG Thursday, April 10, 2014 1:42 PM
    Thursday, April 10, 2014 1:42 PM

All replies

  • Hi,

    I saw that you were using the following in the host application:

     host.Credentials.ClientCertificate.SetCertificate(......


    Please try to modify it as following:

    host.Credentials.ServiceCertificate.SetCertificate(......

    For more information, please try to refer to:
    http://msdn.microsoft.com/en-us/library/ms733098(v=vs.110).aspx .

    Best Regards,
    Amy Peng


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Thursday, April 10, 2014 8:03 AM
    Moderator
  • I had tried that and it didn't work. But I found out the solution. The hash had to be uppercase apparently. Even though the server hash in mmc was lower case the client and server would not communicate unless I made the client certificate in uppercase. Just as a suggestion you might want to provide an example of that working in this article: http://msdn.microsoft.com/en-us/library/ms733791.aspx as an alternative for the FindBySubjectName("contoso.com") section. There is nothing that says in any article I can find that the hash has to be upper case. I found it by using a server callback on the client to see what certificate hash it was expecting.
    • Marked as answer by Ryan MVSG Thursday, April 10, 2014 1:42 PM
    Thursday, April 10, 2014 1:42 PM