所以我很困在这里。我一直能够通过 http 毫无问题地托管 WCF 应用程序。我可以在 IIS 中设置 https WCF 应用程序。但是当我尝试使用自托管的 https wcf 应用程序时,这只不过是一场噩梦。 我在同一台计算机上同时运行客户端和自托管服务。此外,每次我运行该服务时都没有错误地打开它。据报道,状态是开放的。当我尝试与客户端(通过 channel 工厂激活服务)连接时,它因 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 .第一份文件我一字不漏地跟进,最后当作者说“就是这样!现在我们可以调用程序,它会调用服务”时它没有。它给了我一个错误:
"Could not establish trust relationship for the SSL/TLS secure channel".
所以我在阅读第二篇文章时尝试了一种稍微不同的方法。我尝试使用已为我的服务器列出的现有证书(存储在个人证书下)。我复制了指纹并将其注册到创建我自己的应用程序 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();
}
}
}
}
请您参考如下方法:
很可能您的客户在协商过程中拒绝了证书。我怀疑您在主机正在监听的端口上绑定(bind)的证书是自签名的。
如果您对证书固定没问题,您可以在测试环境和生产环境中的客户端上使用这些内容。
/// <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;
}
}