2011-07-01 41 views
11

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

+0

你能通过浏览器访问URL吗?如果是这样,浏览器是否提醒您证书无效? – dlev

回答

17

经过一番研究,我发现了一个博客条目由Jan Tielens这也解释了是怎么回事,和我的问题解决方法:

当您浏览到一个HTTPS网站,你可能会得到一个对话窗口,询问你如果你想信任Web服务器提供的证书。所以接受证书的责任由用户处理。让我们回到web服务场景,如果您想要调用位于使用SSL和HTTPS的Web服务器上的Web服务,则存在问题。当你通过代码进行调用时,没有弹出对话窗口,并询问你是否信任该证书(幸运的是,这在服务器端场景中会非常丑陋)。也许你会得到以下异常:

System.Net.WebException类型的未处理的异常出现在System.dll中
附加信息:基本 连接已经关闭:无法 建立与 远程服务器的信任关系。

但对于这个 问题的解决方案,你可以通过创建自己的 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服务。

3

如果您使用自签名SSL证书或不可信SSL证书,您可以告诉应用程序忽略它(如果您真的想忽略它)。例如

ServicePointManager.ServerCertificateValidationCallback = _ 
     new RemoteCertificateValidationCallback(IgnoreSelfSSL) 

public bool IgnoreSelfSSL(ServicePoint sp, X509Certificate cert,WebRequest req, int problem) { 
    return true; 
} 

您可以任何地方回调将执行之前您的服务请求被击中。

1

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