netty/websocket服务器配置阿里云SSL证书安全访问配置,亲测有效

news2025/1/22 9:16:12

背景:java 微服务包括https访问和websocket访问,当https接口访问ws请求时报错,因为https能访问wss。

申请阿里云免费证书后,搜索各种教程比如nginx配置方式、netty访问证书等。走了不少弯路,终于走通一种。

关键点:1、因为使用了netty,nginx配置wss的方式没有走通。需要将证书放到netty启动的方式启动才可以。

2、网上教程大多数是pkcs12的证书生成方式。但是netty仅仅支持pkcs8 的版本,所以需要生成pkcs12之后再转pkcs8.

一、阿里云申请免费证书

 二、生成pem、key的证书

1、下载类型Nginx的pem证书

2、下载类型Tomcat的pfx 证书,在jdk的路径下cmd命令生成(也可以直接在文件夹里面)server.key文件,输入命令,密码是同时在一起的pfx-password.txt里面

openssl pkcs12 -in *******.pfx -nocerts -nodes -out server.key

 

 

3、因为netty仅仅支持pkcs8,所以将server.key 通过OpenSSl 生成pkcs8的版本

安装openssl

windows电脑下载已经编译好的openssl
OpenSSL for Windows

或者

OpenSSL官方下载 - 码客
然后将安装路径加到环境变量中

cmd 命令生成server8.key:

openssl pkcs8 -topk8 -inform PEM -in server.key -outform pem -nocrypt -out server8.key

 

 

三、编写代码

仅仅需要增加两个地方:

1、启动的start方法,增加server8.key和pem文件的读取

全局变量

private SslContext sslContext;//netty 配置ssl证书、WSS地址访问。备注:netty 仅仅使用pkcs8的证书,需要使用openssl转

 将证书放到main/resources下面,则用ClassPathResource读取

//ssl证书配置--放到项目中
ClassPathResource pem = new ClassPathResource("service.sv3d.cn.pem");
ClassPathResource key = new ClassPathResource("server8.key");
this.sslContext = SslContextBuilder.forServer(pem.getInputStream(),key.getInputStream()).build();

 将证书放到外面,方便后期更换,毕竟免费的证书是一年一申请的,用InputStream读取

//ssl证书配置--放到外部
InputStream pemInputStream = new FileInputStream("E:\\zhengshu\\9760642_service.sv3d.cn_nginx\\9760642_service.sv3d.cn.pem"); /// 证书存放地址
InputStream keyInputStream = new FileInputStream("E:\\zhengshu\\9760642_service.sv3d.cn_tomcat\\server8.key"); /// 证书存放地址
this.sslContext = SslContextBuilder.forServer(pemInputStream,keyInputStream).build();

2、initChannel 方法添加ssl的验证

ch.pipeline().addLast(sslContext.newHandler(ch.alloc()));

3、全部代码,仅看修改部分就行,大同小异。

    /**
     * 启动
     * @throws InterruptedException
     */
    private void start() throws InterruptedException {
    	try {
			port = Integer.parseInt(optionService.getByKey(OptionKey.SocketPort.getKey()).getValue());

			String wsFlag = nacosConfigProp.getWsFlag();
			 //ssl证书配置--放到外部
                //InputStream pemInputStream = new FileInputStream("E:\\zhengshu\\9760642_service.sv3d.cn_nginx\\9760642_service.sv3d.cn.pem"); /// 证书存放地址
                //InputStream keyInputStream = new FileInputStream("E:\\zhengshu\\9760642_service.sv3d.cn_tomcat\\server8.key"); /// 证书存放地址
                //this.sslContext = SslContextBuilder.forServer(pemInputStream,keyInputStream).build();
                //ssl证书配置--放到项目中
                ClassPathResource pem = new ClassPathResource("service.sv3d.cn.pem");
                ClassPathResource key = new ClassPathResource("server8.key");
                this.sslContext = SslContextBuilder.forServer(pem.getInputStream(),key.getInputStream()).build();

		} catch (Exception e) {
			e.printStackTrace();
		}
        //数据量上来时设置线程池
        /*bossGroup = new NioEventLoopGroup(2,new DefaultThreadFactory("server1",true));
        workGroup = new NioEventLoopGroup(4,new DefaultThreadFactory("server2",true));*/
    	// 获取Reactor线程池
    	bossGroup = new NioEventLoopGroup();
        workGroup = new NioEventLoopGroup();
        // 服务端启动辅助类,用于设置TCP相关参数
        ServerBootstrap bootstrap = new ServerBootstrap();
        // bossGroup辅助客户端的tcp连接请求, workGroup负责与客户端之前的读写操作,设置为主从线程模型
        bootstrap.group(bossGroup,workGroup);
        //禁用nagle算法
        bootstrap.childOption(ChannelOption.TCP_NODELAY, true); 
       
        //bootstrap.childOption(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(1024*1024, 40*1024*1024)); 
        
        //当设置为true的时候,TCP会实现监控连接是否有效,当连接处于空闲状态的时候,超过了2个小时,
        //本地的TCP实现会发送一个数据包给远程的 socket,如果远程没有发回响应,TCP会持续尝试11分钟,
        //知道响应为止,如果在12分钟的时候还没响应,TCP尝试关闭socket连接。
        bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true); 
        // 设置NIO类型的channel,设置服务端NIO通信类型
        bootstrap.channel(NioServerSocketChannel.class);
        // 设置监听端口
        bootstrap.localAddress(new InetSocketAddress(port));
        // 连接到达时会创建一个通道,设置ChannelPipeline,也就是业务职责链,由处理的Handler串联而成,由从线程池处理
        bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
        	// 添加处理的Handler,通常包括消息编解码、业务处理,也可以是日志、权限、过滤等
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                // 流水线管理通道中的处理程序(Handler),用来处理业务
                
            	  //=============================增加心跳支持============================

                //添加ssl 访问
                ch.pipeline().addLast(sslContext.newHandler(ch.alloc()));

            	// webSocket协议本身是基于http协议的,所以这边也要使用http编解码器
                ch.pipeline().addLast(new HttpServerCodec());
                ch.pipeline().addLast(new ObjectEncoder());
                //ch.pipeline().addLast(myMessageDncoder);
                //ch.pipeline().addLast(myMessageEncoder);
                // 以块的方式来写的处理器,分块向客户端写数据,防止发送大文件时导致内存溢出,channel.write(new ChunkedFile(new File("...")))
                ch.pipeline().addLast(new ChunkedWriteHandler());
                //ch.pipeline().addLast(new MyServerChunkHandler());
		        /*
		        说明:
		        1、http数据在传输过程中是分段的,HttpObjectAggregator可以将多个段聚合
		        2、这就是为什么,当浏览器发送大量数据时,就会发送多次http请求
		         */
                //需要放到HttpServerCodec后面
		        ch.pipeline().addLast(new HttpObjectAggregator(65535));//10kb?
		        //websocket数据压缩扩展,当添加这个的时候,WebSocketServerProtocolHandler第三个参数需要设置成true
		        ch.pipeline().addLast(new WebSocketServerCompressionHandler());
		        /*
		        说明:
		        1、对应webSocket,它的数据是以帧(frame)的形式传递
		        2、浏览器请求时 ws://localhost:58080/xxx 表示请求的uri
		        3、核心功能是将http协议升级为ws协议,保持长连接
		        */
		       
		        
		        //对客户端,如果在60秒内没有向服务端发送心跳,就主动断开
		        //三个参数分别为读/写/读写的空闲,我们只针对读写空闲检测
		        //ch.pipeline().addLast(new IdleStateHandler(10,11,12,TimeUnit.SECONDS));
		        //ch.pipeline().addLast(heartBeatHandler);
		        
		        // 自定义的handler,处理业务逻辑
		        //ch.pipeline().addLast(webSocketHandler);
		        //ch.pipeline().addLast(userLoginRespHandler);
		        ch.pipeline().addLast(textWebSocketHandler);
		        ch.pipeline().addLast(binaryWebSocketFrameHandler);
		        // 服务器端向外暴露的 web socket 端点,当客户端传递比较大的对象时,maxFrameSize参数的值需要调大
		        ch.pipeline().addLast(new WebSocketServerProtocolHandler(webSocketPath, webSocketProtocol, true, 10485760));//10mb?

            }
        });
        // 配置完成,开始绑定server,通过调用sync同步方法阻塞直到绑定成功
        ChannelFuture channelFuture = bootstrap.bind().sync();
        log.info("Server started and listen on:{}",channelFuture.channel().localAddress());
        // 对关闭通道进行监听
        channelFuture.channel().closeFuture().sync();
    }

四、验证是否通,采用Postman或者自己写界面都行。

配置完了,发现ws不能使用了,还在研究,各位大神有办法,可以留言,互相学习。下面是下载的别人的案例,然后改了下我的案例,所以里面有两个server,可以做下参考。

WebsocketServer1是我的方案,证书按照文章里面的证书下载生成,启动WebsocketServer1的main方法,用postman访问是可以的,但是用他绑定的html不行,但是在我的项目里面是可以的。

java访问案例

另一种方式是WebsocketServer生成key然后配置密码的方式,我尝试过,生成的密码每次都是不匹配,所以放弃了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/468827.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

龙蜥开发者说:亲历从基础设施构建到系统质量保障,龙蜥未来可期 | 第 19 期

「龙蜥开发者说」第 19 期来了&#xff01;开发者与开源社区相辅相成&#xff0c;相互成就&#xff0c;这些个人在龙蜥社区的使用心得、实践总结和技术成长经历都是宝贵的&#xff0c;我们希望在这里让更多人看见技术的力量。本期故事&#xff0c;我们邀请了龙蜥社区开发者宋彦…

【Python】值得收藏,三元一次方程组的计算,快来看看有什么新奇的~~~

三元一次方程组的计算对于大家来说都不陌生了&#xff0c;但是用编程语言来解决方程组问题想必还是会有些大聪明们有点迷糊的&#xff0c;今天就带大家来看看是怎么利用python实现方程组的解集的&#xff1b; 本文主要分成两部分&#xff1a; 解题验算综述 解题 题目1 代码 …

Security中使用Redis管理会话(模拟cookie实现)

配置redis相关 1. 配置Redis package com.zzhua.blog.config.redis;import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.cor…

【HCIP】IPV6综合实验(ripng,ospfv3,bgp,6to4)

目录 一、IP规划 二、 连通公网部分(IPv4) 三、R1、R2上IPv4&#xff0b;v6配置 四、IPV6部分ip配置 五、IPV6部分OSPF&BGP协议配置 Ⅰ、 ospf Ⅱ、bgp 六、联通网络 需求&#xff1a; 1、AR1处于IPV4&#xff0c;也有IPV6的地址&#xff0c;有两个环回 2、AR45678处…

Golang Gin 请求参数绑定与多数据格式处理

之前学习了使用Gin框架的Engine的默认路由功能解析HTTP请求。现在我们来学习gin框架的参数绑定操作和请求结果返回格式。 处理POST请求时&#xff0c;使用context.PostForm或者context.DefaultPostForm获取客户端表单提交的数据。 像上述这种只有username和password两个字段的表…

CS:APP 第7章链接分步编译(cpp/cc1/as/ld)遇到的问题

环境 WSL Ubuntu 22.04.2 LTS gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0 问题 问题一 cc1 命令找不到 cc1 命令在 /usr/lib/gcc/x86_64-linux-gnu/11/cc1 里&#xff0c;注意不同操作系统等可能 cc1 的位置不一样&#xff0c;可以使用 find 或者 locate 命令搜索。 通过下…

聊点技术 | 架构瘦身,让Bonree ONE跑得更轻

4月21日&#xff0c;博睿数据ONE有引力2023春季产品发布会圆满落幕&#xff0c;一体化智能可观测平台Bonree ONE 2023春季正式版正式发布&#xff0c;这一次发布的版本更轻、更强、更智能。 Bonree ONE在上一版基础上削减50%组件数量&#xff0c;下架两大高耗能组件&#xff0c…

97-TCP为什么要有一个“TIME_WAIT“的状态

文章目录 1.TCP为什么要有一个"TIME_WAIT"的状态(1) 可靠的终止 TCP 连接。(2) 保证让迟来的 TCP 报文有足够的时间被识别并被丢弃 ; 2.拓展带外数据 1.TCP为什么要有一个"TIME_WAIT"的状态 "TIME_WAIT"状态存在的原因主要有两点: (1) 可靠的终…

成功经验分享,Nacos注册中心实践,带你玩转Nacos

1、什么是 Nacos &#xff1f; 官方&#xff1a;一个更易于构建云原生应用的动态服务发现(Nacos Discovery )、服务配置(Nacos Config)和服务管理平台。 集&#xff1a; 注册中心配置中心服务管理 平台 nacos的特性包括&#xff1a; 服务发现和服务健康监测动态配置服务动态…

行人检测(人体检测)4:C++实现人体检测(含源码,可实时人体检测)

行人检测(人体检测)4&#xff1a;C实现人体检测(含源码&#xff0c;可实时人体检测) 目录 行人检测(人体检测)4&#xff1a;C实现人体检测(含源码&#xff0c;可实时人体检测) 1. 前言 2. 行人检测(人体检测)检测模型&#xff08;YOLOv5&#xff09; &#xff08;1&#xf…

谈「效」风生 | 如何找到现有研发体系的「内耗问题」?

#第3期&#xff1a;如何找到现有研发体系的「内耗问题」&#xff1f;# 在上一期《谈到提升效能&#xff0c;我们应该如何下手&#xff1f;》我们聊到开始做研发效能的四个要点&#xff1a;评估现有流程、引入自动化工具、建立度量指标、持续改进。本期就围绕「评估现有研发体系…

二次创业接地气、强内功,三只松鼠从一棵树出发重造“人设”

民以食为天&#xff0c;自古以来&#xff0c;“吃”都是一门浅显与深奥并存的生意。产业链看似简单&#xff1a;种、收、制、卖&#xff0c;却足以令众多企业为之前赴后继十年、百年。 三只松鼠&#xff0c;正在这条变革的道路上砥砺前行。自去年4月开启全面转型以来&#xff…

C++ 赋值运算符重载

赋值运算符重载 运算符重载&#xff1a; C为了增强代码的可读性&#xff0c;可以对 运算符 进行重载&#xff0c;运算符重载 就是具有特殊函数名的函数&#xff0c;这个函数也具有返回值类型&#xff0c;函数名字和参数列表&#xff0c;它的返回值和参数列表的形式和普通函数…

基于SAM的二次开发案例收集分享

一、AnyLabeling[1]——制作人&#xff1a;vietanhdev AnyLabeling LabelImg Labelme Improved UI Autolabeling AnyLabeling软件是一个集成了YOLO、Segment Anything模型&#xff08;AI支持&#xff09;的高效数据标注工具&#xff0c;它可以通过点击目标的方式完成目标检…

商业银行财富管理“智能原生”能力呈阶梯化,AI助力商业模式趋向多元化发展

易观&#xff1a;金融业的财富管理从经营角度来看&#xff0c;是“客户与渠道管理场景运营产品研发”三位一体共同构建以客户为中心&#xff0c;数据驱动的业务经营体系。其中&#xff0c;“客户与渠道管理”是将客户利益作为核心目标&#xff0c;通过升级用户体验、客户全生命…

获奖名单公布|香港BlockBooster x Moonbeam黑客松圆满收官

Moonbeam基金会赞助的”Into the Socialverse”主题的BlockBooster黑客松于近日落幕。该活动由BlockBooster、OKX、Gitcoin和OxU香港区块链俱乐部联合主办&#xff0c;共有22个开发团队参赛。经过多位评委的严格筛选&#xff0c;3支优秀团队脱颖而出&#xff0c;获得Moonbeam基…

zookeeper集群命令使用

1.zookeeper脚本使用(地址填写集群中任意一个主机地址) 连接客户端命令行 /etc/zookeeper/zookeeper/bin/zkCli.sh -server 10.1.60.112:2181 启动zookeeper服务 /etc/zookeeper/zookeeper/bin/zkServer.sh start 停止zookeeper服务 /etc/zookeeper/zookeeper/bin/zkServer…

春风吹,战鼓擂,忆享科技-云服务事业部春季员工关怀活动集锦,温情相伴

前言 时序更替&#xff0c;忆享科技又迎来新的一年。回顾2022&#xff0c;忆享科技在风雨中前行&#xff0c;实现了一次又一次的突破。在这2023年春暖花开&#xff0c;万物复苏的美好季节&#xff0c;忆享科技怀抱着它满满的关怀向大家走来&#xff01;春季云服务事业部开展了五…

推动科技企业成长,开源网安受邀参加数字经济企业孵化器建设座谈会

近日&#xff0c;为更好地做好数字经济孵化器的孵化培育工作&#xff0c;推动数字经济孵化器和入驻企业高质量发展&#xff0c;高创公司召开数字经济企业孵化器建设座谈会。高新区工委委员、管委会副主任贺菲出席会议&#xff0c;开源网安合肥公司总经理菅志刚受邀参加本次座谈…

vue生命周期代码示范--Vue基本介绍--MVVM-示意图--数据渲染--事件绑定--修饰符--组件化--和全部代码示范

目录 Vue 基本介绍 官网 git 地址: MVVM-示意图 解读 MVVM 思想(上图) 下载官网 简单的代码示例方便理解 Vue 数据绑定机制分析! 注意事项和使用细节 数据单向渲染 基本说明 应用实例 注意事项和使用细节 数据双向绑定 应用实例 ​编辑代码实现 代码综合-单…