Netty之握手和安全认证
Netty之握手和安全认证
握手的发起是在客户端和服务端TCP链路建立成功通道激活时,握手消息的接入和安全认证在服务端处理。
一. 握手认证的客户端ChannelHandler
握手认证的客户端ChannelHandler,用于在通道激活时发起握手请求
package aggrement;
import java.awt.TrayIcon.MessageType;
importio.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
/*
* 握手认证客户端,用于在通道激活时发起握手请求
*/
public class LoginAuthReqHandler extendsChannelHandlerAdapter{
/*
* 当客户端跟服务端TCP三次握手成功之后,由客户端构造握手请求消息发送给服务端
* 由于采用IP白名单认证机制,因此,不需要携带消息体,消息体为空,消息类型为3
* 握手请求消息,握手请求发送之后,按照协议规范,服务端需要返回握手应答消息
* (non-Javadoc)
* @seeio.netty.channel.ChannelHandlerAdapter#channelActive(io.netty.channel.ChannelHandlerContext)
*/
publicvoid channelActive(ChannelHandlerContext ctx) throws Exception{
ctx.writeAndFlush(buildLoginReq());
}
/*
* 对握手应答消息进行处理,首先判断消息是否是握手应答消息
* 如果不是,直接透传给后面的ChannelHandler进行处理;首先判断是握手应答消息
* 对应答结果进行判断
* (non-Javadoc)
* @seeio.netty.channel.ChannelHandlerAdapter#channelRead(io.netty.channel.ChannelHandlerContext,java.lang.Object)
*/
publicvoid channelRead(ChannelHandlerContext ctx,Object msg) throws Exception{
NettyMessagemessage=(NettyMessage) msg;
//如果是握手应答消息,需要判断是否认证成功
if(message.getHeader()!=null)&&
message.getHeader().getType()==MessageType.LOGIN_RESP.value()){
byteloginResult=(byte) message.getBody();
if(loginResult!=(byte)0) {
//握手失败,关闭连接
ctx.close();
}else {
System.out.println("Loginis ok:"+message);
ctx.fireChannelRead(msg);
}
} else
ctx.fireChannelRead(msg);
}
privateNettyMessage buildLoginReq(){
NettyMessagemessage=new NettyMessage();
Headerheader=new Header();
header.setType(MessageType.LOGIN_REQ.value());
message.setHeader(header);
returnmessage;
}
publicvoid exceptionCaught(ChannelHandlerContext ctx,Throwable cause) throwsException{
ctx.fireExceptionCaught(cause);
}
}
二.服务端握手接入和安全认证LoginAuthRespHandler
package aggrement;
importio.netty.channel.ChannelHandlerAdapter;
importio.netty.channel.ChannelHandlerContext;
import java.awt.TrayIcon.MessageType;
import java.net.InetSocketAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/*
* 服务端的握手接入和安全认证
*/
public class LoginAuthRespHandler extendsChannelHandlerAdapter{
privateMap<String,Boolean> nodeCheck=newConcurrentHashMap<String,Boolean>();
//分别定义了重复登录保护和IP认证的白名单列表,主要用于提升握手的可靠性
privateString[] whitekList={"127.0.0.1","192.168.1.104"};
@Override
publicvoid channelRead(ChannelHandlerContext ctx,Object msg) throws Exception {
NettyMessagemessage=(NettyMessage) msg;
/*
* 用于接入认证,首先根据客户端的原地址(/127.0.0.1:12088)进行重复登录判断
* 如果客户端已经登录成功,拒绝重复登录,以防止由于客户端重复登录导致的句柄泄漏
*
*/
//如果是握手请求消息,处理,其他消息透传
if(message.getHeader()!=null&&message.getHeader().getType()==MessageType.LOGIN_REQ.value)){
StringnodeIndex=ctx.channel().remoteAddress().toString();
NettyMessageloginResp=null;
//重复登录,拒绝
if(nodeCheck.containsKey(nodeIndex)){
loginResp=buildResponse((byte)-1);
} else{
//通过ChannelHandlerContext的Channel接口获取客户端的
//InetSocketAddress地址,从中取得发送方的原地址信息,通过原地址进行白名单校验
//校验通过握手成功,否则握手失败,
InetSocketAddressaddress=(InetSocketAddress) ctx.channel().remoteAddress();
Stringip=address.getAddress().getHostAddress();
booleanisOK=false;
for(StringWIP:whiteList){
if(WIP.equals(ip)){
isIK=true;
break;
}
}
//通过buildResponse构造握手应答消息返回客户端
loginResp=isOK?buildResponse((byte)0):buildResponse((byte) -1);
if(isOK)
nodeCheck.put(nodeIndex,true);
}
System.out.println("Thelogin responseis:"+loginResp+"body["+loginResp.getBody()+"]");
ctx.writeAndFlush(loginResp);
}else {
ctx.fireChannelRead(msg);
}
}
privateNettyMessage buildResponse(byte result){
NettyMessagemessge=new NettyMessage();
Headerheader=new Header();
header.setType(MessageType.LOGIN_RESP.value());
message.setHeader(header);
message.setBody(result);
returnmessage;
}
publicvoid exceptionCautht(ChannelHandlerContext ctx,Throwable cause) throwsException{
nodeCheck.remove(ctx.channel().remoteAddress().toString());
ctx.close();
ctx.fireExceptionCautht(cause);
}
}
当发生异常关闭链路的时候,需要将客户端的消息从登录注册表中去注册,以保证后续客户端可以重连成功。
Netty之握手和安全认证相关推荐
- 使用wireshark观察SSL/TLS握手过程--双向认证/单向认证
SSL/TLS握手过程可以分成两种类型: 1)SSL/TLS 双向认证,就是双方都会互相认证,也就是两者之间将会交换证书. 2)SSL/TLS 单向认证,客户端会认证服务器端身份,而服务器端不会去对客 ...
- 基于Websocket草案10协议的升级及基于Netty的握手实现
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 最近发现 ...
- mysql 挑战握手协议_[中文协议]PPP挑战握手认证协议(CHAP)
组织:中国互动出版网(http://www.china-pub.com/) RFC文档中文翻译计划(http://www.china-pub.com/compters/emook/aboutemook ...
- mqtt连接失败_Netty实战:如何让单机下Netty支持百万长连接?
单机下能不能让我们的网络应用支持百万连接?可以,但是有很多的工作要做.而且要考虑到单机的系统资源消耗能否支撑百万并发 一.操作系统优化 首先就是要突破操作系统的限制. 在Linux平台上,无论编写客户 ...
- Netty 高性能特性
转自:http://www.infoq.com/cn/articles/netty-high-performance/ 1. 背景 1.1. 惊人的性能数据 最近一个圈内朋友通过私信告诉我,通过使用N ...
- reactor线程模型_简单了解Java Netty Reactor三种线程模型
1. Reactor三种线程模型 1.1. 单线程模型 Reactor单线程模型,指的是所有的IO操作都在同一个NIO线程上面完成,NIO线程的职责如下: 1)作为NIO服务端,接收客户端的TCP连接 ...
- 《Netty权威指南》
<Netty权威指南> 基本信息 作者: 李林锋 出版社:电子工业出版社 ISBN:9787121233432 上架时间:2014-5-29 出版日期:2014 年6月 开本:16开 页码 ...
- netty cpu 占用率 高_Netty 是如何支撑高性能网络通信的?
作为一个高性能的 NIO 通信框架,Netty 被广泛应用于大数据处理.互联网消息中间件.游戏和金融行业等.大多数应用场景对底层的通信框架都有很高的性能要求,作为综合性能最高的 NIO 框架 之一,N ...
- 04 | 事件调度层:为什么 EventLoop 是 Netty 的精髓?
1.单线程模型 略- 2.多线程模型 略- 3.主从多线程模型 略- 4.Netty EventLoop 实现原理 4.1.EventLoop 是什么 每当事件发生时,应用程序都会将产生的事件放入事件 ...
最新文章
- 汇编语言(王爽 第三版) ret retf总结 以及检测点10.1
- WordPress 2.9.2 使用感受
- centos6.7一键装机
- boost::hana::none_of用法的测试程序
- C学习杂记(四)sizeof计算联合体大小
- mysql driver 读写分离_Mysql主从复制和读写分离实践
- 解决ASP.NET在IE10中Session丢失问题
- python脚本打包成exe可执行文件
- 文件系统权限引起IIS站点总跳登录页面
- FreeRTOS学习记录(安富莱FreeRTOS教程摘录)
- 我的Delphi开发经验谈(本人修改版) 收藏
- h5课件制作_教师必备:实用H5课件制作技巧
- 评测 AlibabaCloud 阿里云国际版 香港轻量云服务器的性能和网络怎么样
- 快速跳转到行首/行尾 快捷键
- OO第四单元作业小结
- IBM员工回顾与华为合作20周年:这是一支有激情的团队
- 2022年最赚钱地推项目-WiFi贴项目(月入10个W)
- 《C++ Concurrency in Action》笔记28 无锁并行数据结构
- 冯诺依曼原理奠定了至今仍然在使用的计算机,计算机二级MS-Office真题「选择题」...
- XXX售后服务解决方案
热门文章
- Scratch绘制蜘蛛网1
- 欧盟首个数据保护条例GDPR生效,你可能需要这份中文版的全文(丁晓东译) |下...
- Hibernate注解详解(超全面)
- 树莓派PCA9685的舵机MG996R二度自由云台操控代码,搭配mqtt进行远程操控
- robocopy 遷移共享文件夾
- java的sort函数中Comparator的简单使用
- DMA基本概念与常见寄存器设置
- iOS 三方登录 微信登录失败 真机测试 由于应用BundleID信息校验不通过,无法使用微信登录
- 【JavaWeb-遇错】继承或者实现Servlet相关时总是报红或者包导不进来
- 做区块链联盟链开发前期准备