none
WCF self host works, once in iis fails RRS feed

  • Question

  • I have a dummy self hosted service and a console app client while I try to get the hang of https configurations in WCF. They both work fine. But when I move the client code to IIS (made via code, there is no config file on either example) it fails on the certificate validation. I'm confused. It's the same machine I'm running the code on. So why would running a client in IIS effect the way it validates the ssl cert?

    Here is my self host:

    string address = "https://localhost:8009/TestBatchSvc/v3";
                    WSHttpBinding binding = new WSHttpBinding();
                    binding.Security.Mode = SecurityMode.Transport;
                    ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                    smb.HttpsGetEnabled = true;
                    //binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
                    ServiceHost host = new ServiceHost(typeof(TestBatchSvc));
                    host.Description.Behaviors.Add(smb);
                    host.AddServiceEndpoint(typeof(ITestBatchSvc), binding, address);
                    host.Credentials.ServiceCertificate.SetCertificate(System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine, System.Security.Cryptography.X509Certificates.StoreName.My,
                        System.Security.Cryptography.X509Certificates.X509FindType.FindByThumbprint, "e7026ea67f585f963e2597fd2a452eb2300bcf9d".ToUpper());
                    host.Open();

    Here is my client:

    // ... Main() {
    string address = "https://localhost:8009/TestBatchSvc/v3";
                WSHttpBinding binding = new WSHttpBinding();
                binding.Security.Mode = SecurityMode.Transport;
                //binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
    
                try
                {
                    SetCertificatePolicy();
                    string hash = "e7026ea67f585f963e2597fd2a452eb2300bcf9d".ToUpper();
                    ChannelFactory<ITestBatchSvc> factory = new ChannelFactory<ITestBatchSvc>(binding, address);
                    factory.Credentials.ClientCertificate.SetCertificate(System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine, System.Security.Cryptography.X509Certificates.StoreName.My,
                        System.Security.Cryptography.X509Certificates.X509FindType.FindByThumbprint, hash);
                    ITestBatchSvc 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();
    }
    
            /// <summary>
            /// Sets the Certificate Validation Policy for the Client
            /// </summary>
            public static void SetCertificatePolicy()
            {
                ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;
            }
    
            /// <summary>
            /// Allows for validation of SSL conversations with the server. 
            /// </summary>
            private static bool ValidateRemoteCertificate(object sender, X509Certificate cert,
                                                    X509Chain chain, SslPolicyErrors error)
            {
                string hash = "e7026ea67f585f963e2597fd2a452eb2300bcf9d".ToUpper();
                if (cert.GetCertHashString() == hash)
                {
                    return true;
                }
                else
                {
                    Console.WriteLine("Cert hash: {0}", cert.GetCertHashString());
                    Console.WriteLine("Expected: {0}", hash);
                    string text = "Failed to establish secure channel for SSL/TLS."
                                  + Environment.NewLine + Environment.NewLine +
                                  "Connection with server has been disallowed.";
                    Console.WriteLine(text);
                    return false;
                }
            }

    This works just fine. Now if I move the client to a WCF service that tries to use this client code it fails. Basically what I'm trying to do is have a web based WCF service make a localhost call to a self hosted service.

    Friday, April 11, 2014 11:34 AM

Answers

All replies