.NET HttpWebRequest(请求被中止: 未能创建 SSL/TLS 安全通道)和(基础连接已经关闭: 发送时发生错误)问题查找解决

简介: .NET HttpWebRequest(请求被中止: 未能创建 SSL/TLS 安全通道)和(基础连接已经关闭: 发送时发生错误)问题查找解决

前言:

  前段时间在对接第三方接口的时候发生了一个非常奇葩的问题,就是使用 .NET Framework 4.6 HttpWebRequest进行网络请求的相关问题。背景,关于调用第三方的接口都是使用使用自己封装的一个HttpWebRequestHepler帮助类,在本地开发时调用第三方接口都是正常的。然而当我部署到运维给我一个服务器(阿里云服务器)时刚开始提示是请求被中止: 未能创建 SSL/TLS 安全通道,之后经过一番修改以后就是提示基础连接已经关闭: 发送时发生错误。之后尝试了各种方法,还是没有办法解决基础连接已经关闭: 发送时发生错误这个问题。最后真的是无能为力,光这个问题找了一下午的解决方案,最后换到了我自己的阿里云服务器是可以正常调通第三方接口的。然后让运维看了下服务器结果是这个服务器都没有开通外网,所以导致了这个问题的出现。下面记录下问题排除的过程,希望能够帮助到遇到这种坑的小伙伴。

一、自己封装的一个通用的HttpWebRequestHepler Http Web网络请求帮助类:

/// <summary>
    /// Http Web网络请求帮助类
    /// </summary>
    public class HttpWebRequestHepler
    {
        private static HttpWebRequestHepler _httpWebRequestHepler;
        private string _resContent;//响应内容
        private string _errInfo;//错误信息
        private int _responseCode;//响应状态码
        public static HttpWebRequestHepler _
        {
            get => _httpWebRequestHepler ?? (_httpWebRequestHepler = new HttpWebRequestHepler());
            set => _httpWebRequestHepler = value;
        }
        /// <summary>
        /// 数据请求
        /// </summary>
        /// <param name="requestUrl">请求地址</param>
        /// <param name="postData">请求参数</param>
        /// <param name="accessToken">授权token</param>
        /// <param name="contentType">请求标头值类型</param>
        /// <param name="method">请求方式</param>
        /// <returns></returns>
        public string HttpWebResponseData(string requestUrl, string postData, string accessToken = "", string contentType = "application/json", string method = "POST")
        {
            HttpWebResponse wr = null;
            try
            {
                var hp = (HttpWebRequest)WebRequest.Create(requestUrl);
                hp.Timeout = 60 * 1000 * 10;//以毫秒为单位,设置等待超时10分钟
                hp.Method = method;
                hp.ContentType = contentType;
                if (!string.IsNullOrWhiteSpace(accessToken))
                {
                    hp.Headers.Add("Authorization", "Bearer " + accessToken);//增加headers请求头信息
                }
                if (postData != "")//带参数请求
                {
                    byte[] data = Encoding.UTF8.GetBytes(postData);
                    hp.ContentLength = data.Length;
                    Stream ws = hp.GetRequestStream();
                    // 发送数据
                    ws.Write(data, 0, data.Length);
                    ws.Close();
                }
                wr = (HttpWebResponse)hp.GetResponse();
                var sr = new StreamReader(wr.GetResponseStream() ?? throw new InvalidOperationException(), Encoding.UTF8);
                this._resContent = sr.ReadToEnd();
                sr.Close();
                wr.Close();
            }
            catch (Exception exp)
            {
                this._errInfo += exp.Message;
                if (wr != null)
                {
                    this._responseCode = Convert.ToInt32(wr.StatusCode);
                }
                return this._resContent;
            }
            this._responseCode = Convert.ToInt32(wr.StatusCode);
            return this._resContent;
        }
    }

二、请求被中止: 未能创建 SSL/TLS 安全通道问题解决:

  把项目部署到阿里云服务器中,请求第三方提示请求被中止: 未能创建 SSL/TLS 安全通道。首先字面上可以看出来这个https请求安全协议的问题。微软官方说明是,NET 4.6需要添加

ServicePointManager.SecurityProtocol属性,指定schnanel安全包支持的安全协议

微软官方解释:

此属性选择要用于新连接的安全套接字层 (SSL) 或传输层安全性 (TLS) 协议的版本;不会更改现有连接。

从 .NET Framework 4.7 开始,此属性的默认值为 SecurityProtocolType.SystemDefault这允许基于 SslStream ((如 FTP、HTTP 和 SMTP) )的 .NET Framework 网络 api 从操作系统或系统管理员执行的任何自定义配置继承默认安全协议。 有关默认情况下在每个版本的 Windows 操作系统上启用了哪些 SSL/TLS 协议的信息,请参阅 TLS/SSL (SCHANNEL SSP) 中的协议

对于通过 .NET Framework 4.6.2 的 .NET Framework 版本,不会列出此属性的默认值。 安全环境不断变化,默认的协议和保护级别会随着时间的推移而更改,以避免已知的漏洞。 默认值因单独的计算机配置、已安装的软件和应用的修补程序而异。

解决方案:

//todo:指定请求包的安全协议,因为不知道你当前项目到底是哪个版本所以为了安全保障都加上
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.SystemDefault | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;

1336199-20210417184745341-146613190.png

三、基础连接已经关闭: 发送时发生错误

       这个问题查阅了网上几个比较典型的博客试了下,结果都没有办法解决我的问题,一下记录下这几个博客的解决方案,希望可以帮助到遇到这样问题的小伙伴。

1、一般来说添加了上面的ServicePointManager.SecurityProtocol属性就可以解决这个基础连接关闭的问题。

2、C# HttpRequest基础连接已经关闭: 接收时发生意外错误(原文地址):

//增加下面两个属性即可
hp.KeepAlive = false;
hp.ProtocolVersion = HttpVersion.Version10;

四、开启阿里云服务器外网(我的解决方案)

  查看一下你的服务器是否开通了外网,假如没有开通服务器外网在进行尝试。阿里云服务器配置外网访问参考。因为这个奇葩问题花费了一天宝贵的时间,考虑问题还是得多方面考虑。

相关实践学习
通义万相文本绘图与人像美化
本解决方案展示了如何利用自研的通义万相AIGC技术在Web服务中实现先进的图像生成。
7天玩转云服务器
云服务器ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,可降低 IT 成本,提升运维效率。本课程手把手带你了解ECS、掌握基本操作、动手实操快照管理、镜像管理等。了解产品详情:&nbsp;https://www.aliyun.com/product/ecs
相关文章
|
消息中间件 物联网
MQTT常见问题之mqtt 报 MqttException:客户机未连接如何解决
MQTT(Message Queuing Telemetry Transport)是一个轻量级的、基于发布/订阅模式的消息协议,广泛用于物联网(IoT)中设备间的通信。以下是MQTT使用过程中可能遇到的一些常见问题及其答案的汇总:
|
缓存 监控 安全
“您与此网站建立的连接不安全”一招解决
当浏览器提示“您与此网站建立的连接不安全”时,通常表示该网站未使用HTTPS加密链接。解决方法包括:购买并安装SSL证书,强制HTTPS重定向,监控证书有效期,以及全面检查内容来源。普通用户可尝试更新浏览器、清除缓存和Cookies,或使用其他浏览器访问。但根本解决需网站管理员操作。
|
存储 负载均衡 NoSQL
一文让你搞懂 zookeeper
一文让你搞懂 zookeeper
18773 16
|
安全 API C#
C# 如何让程序后台进程不被Windows任务管理器强制结束
C# 如何让程序后台进程不被Windows任务管理器强制结束
531 0
|
监控
查看服务器/IIS日志、log、访问信息基本方法
除了手动查看,你也可以使用日志分析工具,如Log Parser、AWStats等,这些工具可以帮助你更方便地分析日志数据。
2579 1
|
JSON JavaScript 数据格式
详细解读CococCreator跨域访问资源服务器
详细解读CococCreator跨域访问资源服务器
315 0
|
前端开发 小程序
【微信小程序5】利用canvas实现纯色背景抠图功能
【微信小程序5】利用canvas实现纯色背景抠图功能
776 0
|
运维 安全 网络安全
.NET HttpWebRequest(请求被中止: 未能创建 SSL/TLS 安全通道)和(基础连接已经关闭: 发送时发生错误)问题查找解决
.NET HttpWebRequest(请求被中止: 未能创建 SSL/TLS 安全通道)和(基础连接已经关闭: 发送时发生错误)问题查找解决
1579 0
.NET HttpWebRequest(请求被中止: 未能创建 SSL/TLS 安全通道)和(基础连接已经关闭: 发送时发生错误)问题查找解决
|
存储 Java 分布式数据库
什么是HBase?它的特点是什么?
什么是HBase?它的特点是什么?
1284 0