通过HTTPS使用Web服务时抛出System.Net.WebException

当使用HTTPS调用在服务器上运行的Web服务时,我的应用程序抛出System.Net.WebException,并显示消息“底层连接已关闭:无法与远程服务器建立信任关系”。 我不知道如何解决这个问题并成功拨打电话。

经过一些研究,我找到了Jan Tielens的一篇博客文章,其中解释了我的问题以及解决方法:

当您浏览到HTTPS站点时,您可能会看到一个对话窗口,询问您是否要信任Web服务器提供的证书。 因此,接受证书的责任由用户处理。 让我们回到webservice场景,如果你想调用位于使用SSL和HTTPS的web服务器上的web服务,就会出现问题。 当您从代码进行调用时,没有弹出对话框窗口,并询问您是否信任该证书(幸运的是,因为这在服务器端方案中非常难看); 可能你会得到以下exception:

System.dll中发生System.Net.WebException类型的未处理exception
附加信息:基础连接已关闭:无法与远程服务器建立信任关系。

但是有一个解决此问题的方法,您可以通过创建自己的CertificatePolicy类(实现ICertificatePolicy接口)在代码中解决此问题。 在这个类中,您必须编写自己的CheckValidationResult函数,该函数必须返回truefalse ,就像在对话框窗口中按yes或no一样。 出于开发目的,我创建了以下接受所有证书的类,因此您将不再获得令人讨厌的WebException

 public class TrustAllCertificatePolicy : System.Net.ICertificatePolicy { public TrustAllCertificatePolicy() { } public bool CheckValidationResult(ServicePoint sp, X509Certificate cert, WebRequest req, int problem) { return true; } } 

如您所见, CheckValidationResult函数始终返回true,因此所有证书都将受信任。 如果要使此类更安全一些,可以使用X509Certificate参数添加其他检查。 要使用此CertificatePolicy ,您必须告诉ServicePointManager使用它:

 System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy(); 

在调用您的Web服务之前,必须完成此操作(在应用程序生命周期中一次)。

如果您使用的是自签名SSL证书或不受信任的SSL证书,则可以告诉您的应用程序忽略它(如果您确实要忽略它)。 例如

 ServicePointManager.ServerCertificateValidationCallback = _ new RemoteCertificateValidationCallback(IgnoreSelfSSL) public bool IgnoreSelfSSL(ServicePoint sp, X509Certificate cert,WebRequest req, int problem) { return true; } 

您可以在执行服务调用之前将回调放置在任何位置。

答案中给出的提示应仅用于测试 。 对于接受/生产,您应该在机器上安装WS证书,调用WS,并在调用WS-expiration,subject等之前进行证书validation。然后,您可以通过SoapHttpClientProtocol.Proxy.ClientCertificates将此证书添加到WS请求中。