开发者

System.Net.WebException thrown when consuming a web service over HTTPS

开发者 https://www.devze.com 2023-03-17 05:43 出处:网络
When making a call to a web service running on a server using HTTPS my application throws a System.Net.WebException with the message \"The underlying connecti开发者_如何学Goon was closed:Could not est

When making a call to a web service running on a server using HTTPS my application throws a System.Net.WebException with the message "The underlying connecti开发者_如何学Goon was closed: Could not establish trust relationship with remote server". I'm not sure how to get around this issue and successfully make the call.


After some research, I found a blog entry by Jan Tielens which explains what is going on and a workaround for my problem:

When you browse to a HTTPS site, you probably get a dialog window asking you if you want to trust the certificate provided by the webserver. So the responsibility of accepting the certificate is handled by the user. Let's get back to the webservice scenario, if you want to invoke a webservice located on a webserver which uses SSL and HTTPS there is a problem. When you make the call from code, there is no dialog window popping up, and asking if you trust the certificate (luckily because this would be pretty ugly in server-side scenarios); probably you'll get following exception:

An unhandled exception of type System.Net.WebException occurred in System.dll
Additional information: The underlying connection was closed: Could not establish trust relationship with remote server.

But there is a solution for this problem, you can solve this in your code by creating your own CertificatePolicy class (which implements the ICertificatePolicy interface). In this class you will have to write your own CheckValidationResult function that has to return true or false, like you would press yes or no in the dialog window. For development purposes I've created the following class which accepts all certificates, so you won't get the nasty WebException anymore:

public class TrustAllCertificatePolicy : System.Net.ICertificatePolicy
{
    public TrustAllCertificatePolicy() { }

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

As you can see the CheckValidationResult function always returns true, so all certificates will be trusted. If you want to make this class a little bit more secure, you can add additional checks using the X509Certificate parameter for example. To use this CertificatePolicy, you'll have to tell the ServicePointManager to use it:

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

This must be done (one time during the application life cycle) before making the call to your webservice.


If you're using a self signed SSL cert, or an untrusted SSL cert, you can tell your application to ignore it (If you really want to ignore it). e.g.

ServicePointManager.ServerCertificateValidationCallback = _
      new RemoteCertificateValidationCallback(IgnoreSelfSSL)

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

You can place the callback anywhere that will be hit prior to executing your service call.


Tips given in answers should be used only for testing. For acceptance/production you should have WS certificate installed on machine making call to WS, and make certificate validation before calling WS - expiration, subject etc. Then you can add this certificate to WS request through SoapHttpClientProtocol.Proxy.ClientCertificates.

0

精彩评论

暂无评论...
验证码 换一张
取 消