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

时间:2020-01-10 17:08:48   收藏:0   阅读:1814

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

笔者本地使用了两个Websocket技术原型,一个基于Netty封装的Websocket框架:/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> 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;
        }
}

调用结果

技术分享图片

 

 

JSR356

 

原文:https://www.cnblogs.com/passedbylove/p/12177029.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!