首页 > 其他分享 >websocket中获取客户端通信的真实IP

websocket中获取客户端通信的真实IP

时间:2022-10-13 22:04:51浏览次数:63  
标签:return String remoteAddress IP session log websocket holder 客户端

一些场景中,我们要对websocket客户端的ip进行校验,如果是黑名单,或者不被允许的则不应该让他访问业务系统。

笔者本地使用了两个Websocket技术原型,一个基于Netty封装的Websocket框架:​​YeautyYE​​​/​​netty-websocket-spring-boot-starter​

另外一个是基于​​JSR-356 Java Api for websocket​​实现的框架,实现的客户端很多,比如tomcat,spring也有对应的支持。

 

 表达式获得方法

websocket中获取客户端通信的真实IP_ip地址

 

 

 因为使用Ognl解析对象时,会把对象数据放入一棵树,在任意调试窗口监控可以查看到类及属性的层次关系。

比如查询Ip地址,我们这里选择的树路径是

#root->channel->remoteAddress

他返回的对象时InetSocketAddress的实例,得到这个对象后,你可以调用

.getAddress().getHostAddress()
方法获得最终的ip真实地址,当然你也可以使用其他表达式来获得
#root.channel.remoteAddress.holder.addr.holder.hostName
#root.channel.remoteAddress.holder.addr.hostName

这些表达式需要你自己去评估计算。

netty-websocket-spring-boot-starter

封装代码如下:

import lombok.extern.slf4j.Slf4j;
import ognl.DefaultMemberAccess;
import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlException;
import org.yeauty.pojo.Session;


@Slf4j
public final class NettyWebsocketHelper {
private NettyWebsocketHelper() {
}

private static OgnlContext context = new OgnlContext();

/**
* set DefaultMemberAccess with allowed access into the context
*/
static {
context.setMemberAccess(new DefaultMemberAccess(true));
}


public static String getRemoteAddress(final Session session) {
//.getAddress().getHostAddress()
//.holder.addr.hostName
//.holder.addr.holder.address
//.holder.addr.holder.hostName
//return (String) eval(session,"#root.channel.remoteAddress");
return eval(session, "#root.channel.remoteAddress.getAddress().getHostAddress()", String.class);
}

public static <T> T eval(final Object source, final String expression, Class<T> targetClass) {
try {
return (T) Ognl.getValue(expression, context, source);
} catch (OgnlException e) {
log.error("评估表达式出错:{}", e);
throw new IllegalAccessError("expression invalid");
}
}

public static Object eval(final Object source, final String expression) {
Object value = null;
try {
value = Ognl.getValue(expression, context, source);
log.info("return value :{}, class.name:{}", value, value.getClass().getName());
} catch (OgnlException e) {
log.error("评估表达式出错:{}", e);
}
return value;
}
}

使用方法:

/***
* 登录ws服务器
* @param session
* @param appId
* @param apiKey
* @throws InterruptedException
*/
private void onLogin(Session session, String appId, String apiKey) {

String remoteAddress = NettyWebsocketHelper.getRemoteAddress(session);

ApiService service = apiService.getService(appId, apiKey);

if (Objects.isNull(service)) {
session.sendText("appid无效");
session.close();
return;
}

final String serviceType = service.getServiceType();

final Integer serviceId = service.getId();

log.info("远程IP:{}正在尝试登录到api服务器", remoteAddress);

if (!checkWhiteList(serviceId, remoteAddress)) {
session.sendText("禁止调用API接口的IP:".concat(remoteAddress));
session.close();
return;
}
}

调用结果

websocket中获取客户端通信的真实IP_ip地址_02

2020-1-15日更新:

参考:https://stackoverflow.com/questions/22690907/client-socket-get-ip-java

/***
* 登录ws服务器
* @param session
* @param appId
* @param apiKey
* @throws InterruptedException
*/
private void onLogin(Session session, String appId, String apiKey) {
String ip = resolveRemoteIp(session.remoteAddress());

log.info("远程IP地址:{}",ip);
}

String resolveRemoteIp(SocketAddress socketAddress)
{
if (socketAddress instanceof InetSocketAddress) {
InetAddress inetAddress = ((InetSocketAddress)socketAddress).getAddress();
if (inetAddress instanceof Inet4Address) {
log.info("IPv4:{}",inetAddress);
return inetAddress.getHostAddress();
}else if (inetAddress instanceof Inet6Address) {
log.info("IPv6:{}",inetAddress);
}else {
log.error("Not an IP address.");
return null;
}
} else {
log.error("Not an internet protocol socket.");
}
return null;
}

 

JSR356

 

标签:return,String,remoteAddress,IP,session,log,websocket,holder,客户端
From: https://blog.51cto.com/u_296714/5754711

相关文章

  • eclipse使用
    下载​​参考​​​​下载地址​​​​版本介绍​​M1-M9就是说是Eclipse3的几个重要的里程碑版本,MilestoneRCx是发行候选版本!Release--正式发行版beta--测试版​​历史......
  • P1541 [NOIP2010 提高组] 乌龟棋
    [NOIP2010提高组]乌龟棋题目背景小明过生日的时候,爸爸送给他一副乌龟棋当作礼物。题目描述乌龟棋的棋盘是一行\(N\)个格子,每个格子上一个分数(非负整数)。棋盘第1格是......
  • JavaScript高级程序设计笔记10 函数Function
    函数1.几种实例化函数对象的方式以函数声明的方式定义函数表达式箭头函数(arrowfunction)使用Function构造函数接收任意多个字符串参数,最后一个参数始终会被......
  • 通过aud$定位使用错误密码登陆数据库的客户端具体信息
    文档课题:通过aud$定位使用错误密码登陆数据库的客户端具体信息.数据库:oracle11.2.0.464位系统:centos7.964位应用场景:oracle11g存在密码延迟验证的特性,如果输入错误密码......
  • 一周第二次课(3月20日)1.6/1.7 配置IP 1.8 网络问题排查
    1.6/1.7配置IP配置IP的作用:1、使虚拟机可以和外部通信,通过远程连接虚拟机            2、使虚拟机可以上网配置IP的步骤:1、自动获取IP#dhclient ......
  • MYSQL-->客户端常用工具指令
    mysql这个mysql指的是mysql的客户端管理工具语法mysql选项数据库选项内容-u指定用户名-p指定密码-h指定ip地址-P指定端口-e执行SQL语句并退出-e选项可......
  • iPad也能写代码,Lightly今日正式上架 iPad AppStore
    “叮!您的需求现已完成评估和开发,Lightly现已正式推出iPad版本!”现在就到苹果AppStore上搜索「Lightly」,在iPad上体验轻量且功能强大的集成开发工具。Lightly是由TeamCode出......
  • pip常用命令
    pip常用命令:bundle,创建包含多个包的pybundles;freeze,显示所有已安装的包;help,显示可用命令;install,安装包;search,搜索PyPi;uninstall,卸载包;unzip,解压缩单个包;zip,压缩单......
  • JavaScript 常用 工具类
    /***工具类*2022年7月8日22:52:24*//***空校验null或""都返回true*/exportfunctionisEmpty(obj){if((typeofobj==='string')){......
  • CF605E Intergalaxy Trips
    linkSolution不是很难,不知道为啥之前没做出来。不难看出我们有如下转移式:\[f_{u}=\sumf_{v}\timesP_{u,v}\times(\prod_{f_t<f_v}(1-P_{u,t}))+1\]那么我们可以发......