WCF自助主机通过Https失败

时间:2014-04-09 15:33:15

标签: c# wcf host self

所以我很困在这里。我总是能够通过http来托管WCF应用程序。我可以在IIS中设置https WCF应用程序。但是,当我尝试使用自托管的https wcf应用程序时,这只不过是一场噩梦。 我在同一台计算机上运行客户端和自托管服务。此外,每次运行时都会打开服务,没有错误。据报道,该州是开放的。当我尝试连接客户端(通过通道工厂激活服务)时,它会崩溃并出现SSL / TLS错误,如下所述。我已经在这里呆了大约2天了,无法让它发挥作用:(

我尝试过以下几个指南,例如(但不限于)这些指南:http://blogs.msdn.com/b/james_osbornes_blog/archive/2010/12/10/selfhosting-a-wcf-service-over-https.aspx以及此处:http://msdn.microsoft.com/en-us/library/ms733791.aspx。第一个文件我跟着它写信,最后当作者说“那就是它!现在我们可以调用程序,它将调用服务”它没有。它给了我一个错误:

  

“无法为SSL / TLS安全通道建立信任关系”。

所以我在第二篇文章中尝试了一种稍微不同的方法。我尝试使用已经为我的服务器列出的现有认证(存储在个人认证下)。我复制了指纹并将其注册到创建我自己的应用ID的端口。这没用,所以我想好了,试着通过指定客户端凭据并通过指纹查找来强制客户端证书指纹在服务和客户端上,如下所示:

factory.Credentials.ClientCertificate.SetCertificate(
    StoreLocation.LocalMachine, 
    StoreName.My,          
    X509FindType.FindByThumbprint, 
    "The actual thumbprint is here in my code");

我仍然得到相同的结果。我错过了什么?这是服务和客户端的代码。

客户端:

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();
        }
    }
}

服务:

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();
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您的客户可能在协商过程中拒绝了证书。我怀疑您绑定在主机正在侦听的端口上的证书是自签名的。

您可以在测试环境中的客户端上使用这些内容,如果您可以使用证书固定,则可以生成。

/// <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)
{
    if (cert.GetCertHashString() == "Your Certificate SHA1 HashString")
    {
       return true;
    }
    else
    {
       string text = "Failed to establish secure channel for SSL/TLS." 
                     + Environment.NewLine + Environment.NewLine +
                     "Connection with server has been disallowed.";
       MessageBox.Show(text, @"SSL Validation Failure", 
                    MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
       return false;
    }
}