一些场景中,我们要对websocket客户端的ip进行校验,如果是黑名单,或者不被允许的则不应该让他访问业务系统。
笔者本地使用了两个Websocket技术原型,一个基于Netty封装的Websocket框架:YeautyYE/netty-websocket-spring-boot-starter
另外一个是基于JSR-356 Java Api for websocket实现的框架,实现的客户端很多,比如tomcat,spring也有对应的支持。
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 eval(final Object source, final String expression, Class 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;
}
}
调用结果
JSR356
标签:websocket,String,IP,value,session,import,return,final,客户端
来源: /passedbylove/p/12177029.html