From 940773b4e5e70c1b65e71be095632d5dc1c9182d Mon Sep 17 00:00:00 2001 From: zhangdaiscott <zhangdaiscott@163.com> Date: Tue, 19 Jul 2022 19:11:59 +0800 Subject: [PATCH] websocket增加token校验,解决安全问题 --- jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/WebSocketConfig.java | 15 +++++++++++++++ jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/filter/RequestBodyReserveFilter.java | 35 +++++++++++++++++++++++++++++++++++ jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/filter/WebsocketFilter.java | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 0 deletions(-) create mode 100644 jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/filter/RequestBodyReserveFilter.java create mode 100644 jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/filter/WebsocketFilter.java diff --git a/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/WebSocketConfig.java b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/WebSocketConfig.java index 52230f8..597e7b4 100644 --- a/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/WebSocketConfig.java +++ b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/WebSocketConfig.java @@ -1,5 +1,7 @@ package org.jeecg.config; +import org.jeecg.config.filter.WebsocketFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; @@ -19,4 +21,17 @@ public class WebSocketConfig { return new ServerEndpointExporter(); } + @Bean + public WebsocketFilter websocketFilter(){ + return new WebsocketFilter(); + } + + @Bean + public FilterRegistrationBean getFilterRegistrationBean(){ + FilterRegistrationBean bean = new FilterRegistrationBean(); + bean.setFilter(websocketFilter()); + bean.addUrlPatterns("/websocket/*", "/eoaSocket/*", "/newsWebsocket/*", "/vxeSocket/*"); + return bean; + } + } diff --git a/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/filter/RequestBodyReserveFilter.java b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/filter/RequestBodyReserveFilter.java new file mode 100644 index 0000000..fd4f07a --- /dev/null +++ b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/filter/RequestBodyReserveFilter.java @@ -0,0 +1,35 @@ +package org.jeecg.config.filter; + +import org.jeecg.common.constant.CommonConstant; +import org.jeecg.config.sign.util.BodyReaderHttpServletRequestWrapper; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; + +/** + * 针对post请求,将HttpServletRequest包一层 保留body里的参数 + * @Author taoYan + * @Date 2022/4/25 19:19 + **/ +public class RequestBodyReserveFilter implements Filter { + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + ServletRequest requestWrapper = null; + + if(servletRequest instanceof HttpServletRequest) { + HttpServletRequest req = (HttpServletRequest) servletRequest; + // POST请求类型,才获取POST请求体 + if(CommonConstant.HTTP_POST.equals(req.getMethod())){ + requestWrapper = new BodyReaderHttpServletRequestWrapper(req); + } + } + + if(requestWrapper == null) { + filterChain.doFilter(servletRequest, servletResponse); + } else { + filterChain.doFilter(requestWrapper, servletResponse); + } + } +} diff --git a/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/filter/WebsocketFilter.java b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/filter/WebsocketFilter.java new file mode 100644 index 0000000..89a2abc --- /dev/null +++ b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/filter/WebsocketFilter.java @@ -0,0 +1,52 @@ +package org.jeecg.config.filter; + +import lombok.extern.slf4j.Slf4j; +import org.jeecg.common.api.CommonAPI; +import org.jeecg.common.util.RedisUtil; +import org.jeecg.common.util.SpringContextUtils; +import org.jeecg.common.util.TokenUtils; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * websocket 前端将token放到子协议里传入 与后端建立连接时需要用到http协议,此处用于校验token的有效性 + * @Author taoYan + * @Date 2022/4/21 17:01 + **/ +@Slf4j +public class WebsocketFilter implements Filter { + + private static final String TOKEN_KEY = "Sec-WebSocket-Protocol"; + + private static CommonAPI commonApi; + + private static RedisUtil redisUtil; + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + if (commonApi == null) { + commonApi = SpringContextUtils.getBean(CommonAPI.class); + } + if (redisUtil == null) { + redisUtil = SpringContextUtils.getBean(RedisUtil.class); + } + HttpServletRequest request = (HttpServletRequest)servletRequest; + String token = request.getHeader(TOKEN_KEY); + + log.info("websocket连接 Token安全校验,Path = {},token:{}", request.getRequestURI(), token); + + try { + TokenUtils.verifyToken(token, commonApi, redisUtil); + } catch (Exception exception) { + log.error("websocket连接校验失败,{},token:{}", exception.getMessage(), token); + return; + } + HttpServletResponse response = (HttpServletResponse)servletResponse; + response.setHeader(TOKEN_KEY, token); + filterChain.doFilter(servletRequest, servletResponse); + } + +} -- libgit2 0.22.2