WebClient + HTTPS 问题

62

我目前正在与第三方创建的系统进行集成。该系统要求我使用XML/HTTPS发送请求。第三方向我发送了证书并且我已经安装了它。

我使用以下代码:

using (WebClient client = new WebClient())
{
   client.Headers.Add(HttpRequestHeader.ContentType, "text/xml");

   System.Text.ASCIIEncoding  encoding=new System.Text.ASCIIEncoding();
   var response = client.UploadData(address, "POST", encoding.GetBytes(msg));
}

这段代码返回以下WebException

基础连接已关闭:无法建立 SSL/TLS 安全信道的信任关系。

更新 由于我正在使用一个测试服务器,证书不可信并且验证失败... 在测试/调试环境中绕过此问题,创建一个新的ServerCertificateValidationCallback

ServicePointManager.ServerCertificateValidationCallback += new System.Net.Security.RemoteCertificateValidationCallback(bypassAllCertificateStuff);

这是我的“假”回调函数

private static bool bypassAllCertificateStuff(object sender, X509Certificate cert, X509Chain chain, System.Net.Security.SslPolicyErrors error)
{
   return true;
}

点击此处此处查看更多信息。


点击这里 - Lonzo
4
感谢你更新并附上了你使用的代码,因为这样对我来说很方便快捷。+1 - Jeremy Mullin
当调试SSL Web服务时,这非常有用,而不是将Fiddler CA根注册到我的开发机器上!我只需在添加虚拟回调的部分周围加上#if DEBUG,以避免将其放入生产代码中。 - jishi
1
这对于.NET 4.5肯定有效,但不适用于4.6。我想知道为什么。 - RJB
3个回答

71

允许所有证书的最短代码表示实际上是:

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

对于这个错误非常有效。毋庸置疑,你需要提供一个实现,实际检查证书,并基于证书信息决定通信是否安全。为了测试目的,请使用以上代码行。


确实对我的集成测试非常有帮助! - Morten Nørgaard
vb.net版本:ServicePointManager.ServerCertificateValidationCallback = Function() True - AliReza Sabouri

8

以下是原答案的VB.NET版本(当需要使用“AddressOf”运算符来连接事件时,转换器的效果不佳)。在使用WebClient()或HttpWebRequest()对象之前,先放置第一段代码:

ServicePointManager.ServerCertificateValidationCallback = New System.Net.Security.RemoteCertificateValidationCallback(AddressOf bypassAllCertificateStuff)

...以及有线方法代码:

Private Shared Function bypassAllCertificateStuff(ByVal sender As Object, ByVal cert As X509Certificate, ByVal chain As X509Chain, ByVal [error] As System.Net.Security.SslPolicyErrors) As Boolean
    Return True
End Function

-1

试试这个,它有效:

class Ejemplo
{
    static void Main(string[] args)
    {
        string _response = null;
        string _auth = "Basic";
        Uri _uri = new Uri(@"http://api.olr.com/Service.svc");

        string addres = @"http://api.olr.com/Service.svc";
        string proxy = @"http://xx.xx.xx.xx:xxxx";
        string user = @"platinum";
        string pass = @"01CFE4BF-11BA";


        NetworkCredential net = new NetworkCredential(user, pass);
        CredentialCache _cc = new CredentialCache();

        WebCustom page = new WebCustom(addres, proxy);
        page.connectProxy();

        _cc.Add(_uri, _auth, net);

        page.myWebClient.Credentials = _cc;

        Console.WriteLine(page.copyWeb());
    }

}

public class WebCustom
{
        private string proxy;
        private string url;
        public WebClient myWebClient;
        public WebProxy proxyObj;
        public string webPageData;


        public WebCustom(string _url, string _proxy)
        {
            url = _url;
            proxy = _proxy;
            myWebClient = new WebClient();
        }

        public void connectProxy()
        {
            proxyObj = new WebProxy(proxy, true);
            proxyObj.Credentials = CredentialCache.DefaultCredentials;
            myWebClient.Proxy = proxyObj;
        }

        public string copyWeb()
        { return webPageData = myWebClient.DownloadString(url); }
}

2
请问您能否解释一下您的解决方案如何修复HTTP_S_问题? - Johnny Graber

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接