ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; 调用对方提供的webservice 方法之前,加上这一句,即可解决。 ———————————————— 版权声明:本文为CSDN博主「qq_42072922」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_42072922/article/details/82620052
View Details在后台代码中进行基于https协议的请求时,我们经常会遇到一个错误:The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel(基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系。) 1,先加入命名空间: using System.Net.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; 2,再重载CheckValidationResult方法,返回true private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; } 3.然后在执行请求的代码之前加上 ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate; 通过以上三步忽略证书的错误,但是不安全,其他解决方式可以参考https://stackoverflow.com/questions/703272/could-not-establish-trust-relationship-for-ssl-tls-secure-channel-soap 然而,对于一些https接口,加了上述代码之后,调用时回报错:基础连接已经关闭: 发送时发生错误 发生该错误的原因是,使用上述代码默认是以ssl安全协议进行的,但是有些https接口服务并没有使用ssl安全协议,具体参考 https://stackoverflow.com/questions/28286086/default-securityprotocol-in-net-4-5 解决方案1:硬编码,枚举出所有的安全协议,比较简单 在ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate;这行代码前面加上如下代码: ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; 解决方案2:让OS自动选择安全协议(推荐) https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls from:https://blog.csdn.net/ujm097/article/details/89334667
View Details前面的文章说了怎么实现代理类的生成我使用。 在使用的过程 中我又碰到了一个很棘手的问题这是我的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
//官方查询结果xml [WebMethod ] public OrderNciis GetNciisResult(string onName, string onId) { //获取授权文件 string inLicense = LotteryMethods.GetContext(11); //生成的WSDL类() nciicGetCondition objText = new nciicGetCondition(); //获取基础URL objText.Url = LotteryMethods.GetContext(12); //编码 objText.RequestEncoding = Encoding.UTF8; //创建证书文件 X509Certificate objx509 = new X509Certificate(System.Configuration.ConfigurationSettings.AppSettings["cd"].ToString().Trim()); //证书 objText.ClientCertificates.Add(objx509); //方式可有可无 objText.UserAgent = "Client Cert Sample"; //读XML文件 string inConditions = OrderNciisXml(onName, onId); //返回查询结果XML OrderNciis model = new OrderNciis(); model.onLottery = objText.nciicCheck(inLicense, inConditions); return model; } |
代码应该是没有问题,在本地的Vs里测试没有问题,如果在ISS里使用时报基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系”证书验证失败 城刚开始我还以为是文章路径的问题,结果不是, 接着找,后来认为是IIS里配置问题,还是不对,后来,看到 网上也有很多这的问题,但是没有真正解决的,一般都 是在说怎么生成代理类,还有带有证书的过程 我想了想,还是自己想办法解决吧,我把代理类分析了一下才知道 ,原来证书是在代理类里验证的,验证后会返回一个值 表示是否通过,这就好看了, 我们定义一个方法
1 2 3 4 5 6 7 |
private static bool RemoteCertificateValidate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error){ // trust any certificate!!! System.Console.WriteLine("Warning, trust any certificate"); //为了通过证书验证,总是返回true return true; } |
只要这个方法返回为True不就完了吗?呵呵 还需要几个命名空间
1 2 3 4 |
using System.Net; using System.Net.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; |
这个应该在什么时候调用呢,当然 是在构造器里合适些
1 2 3 4 5 6 |
/// <remarks/> public nciicGetCondition() { //验证服务器证书回调自动验证 ServicePointManager.ServerCertificateValidationCallback += RemoteCertificateValidate; } |
from:https://www.cnblogs.com/sufei/archive/2010/03/23/1692811.html
View Details