Commit 940773b4e5e70c1b65e71be095632d5dc1c9182d

Authored by zhangdaiscott
1 parent 2be6e884

websocket增加token校验,解决安全问题

jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/WebSocketConfig.java
1 1 package org.jeecg.config;
2 2  
  3 +import org.jeecg.config.filter.WebsocketFilter;
  4 +import org.springframework.boot.web.servlet.FilterRegistrationBean;
3 5 import org.springframework.context.annotation.Bean;
4 6 import org.springframework.context.annotation.Configuration;
5 7 import org.springframework.web.socket.server.standard.ServerEndpointExporter;
... ... @@ -19,4 +21,17 @@ public class WebSocketConfig {
19 21 return new ServerEndpointExporter();
20 22 }
21 23  
  24 + @Bean
  25 + public WebsocketFilter websocketFilter(){
  26 + return new WebsocketFilter();
  27 + }
  28 +
  29 + @Bean
  30 + public FilterRegistrationBean getFilterRegistrationBean(){
  31 + FilterRegistrationBean bean = new FilterRegistrationBean();
  32 + bean.setFilter(websocketFilter());
  33 + bean.addUrlPatterns("/websocket/*", "/eoaSocket/*", "/newsWebsocket/*", "/vxeSocket/*");
  34 + return bean;
  35 + }
  36 +
22 37 }
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/filter/RequestBodyReserveFilter.java 0 → 100644
  1 +package org.jeecg.config.filter;
  2 +
  3 +import org.jeecg.common.constant.CommonConstant;
  4 +import org.jeecg.config.sign.util.BodyReaderHttpServletRequestWrapper;
  5 +
  6 +import javax.servlet.*;
  7 +import javax.servlet.http.HttpServletRequest;
  8 +import java.io.IOException;
  9 +
  10 +/**
  11 + * 针对post请求,将HttpServletRequest包一层 保留body里的参数
  12 + * @Author taoYan
  13 + * @Date 2022/4/25 19:19
  14 + **/
  15 +public class RequestBodyReserveFilter implements Filter {
  16 +
  17 + @Override
  18 + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  19 + ServletRequest requestWrapper = null;
  20 +
  21 + if(servletRequest instanceof HttpServletRequest) {
  22 + HttpServletRequest req = (HttpServletRequest) servletRequest;
  23 + // POST请求类型,才获取POST请求体
  24 + if(CommonConstant.HTTP_POST.equals(req.getMethod())){
  25 + requestWrapper = new BodyReaderHttpServletRequestWrapper(req);
  26 + }
  27 + }
  28 +
  29 + if(requestWrapper == null) {
  30 + filterChain.doFilter(servletRequest, servletResponse);
  31 + } else {
  32 + filterChain.doFilter(requestWrapper, servletResponse);
  33 + }
  34 + }
  35 +}
... ...
jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/filter/WebsocketFilter.java 0 → 100644
  1 +package org.jeecg.config.filter;
  2 +
  3 +import lombok.extern.slf4j.Slf4j;
  4 +import org.jeecg.common.api.CommonAPI;
  5 +import org.jeecg.common.util.RedisUtil;
  6 +import org.jeecg.common.util.SpringContextUtils;
  7 +import org.jeecg.common.util.TokenUtils;
  8 +
  9 +import javax.servlet.*;
  10 +import javax.servlet.http.HttpServletRequest;
  11 +import javax.servlet.http.HttpServletResponse;
  12 +import java.io.IOException;
  13 +
  14 +/**
  15 + * websocket 前端将token放到子协议里传入 与后端建立连接时需要用到http协议,此处用于校验token的有效性
  16 + * @Author taoYan
  17 + * @Date 2022/4/21 17:01
  18 + **/
  19 +@Slf4j
  20 +public class WebsocketFilter implements Filter {
  21 +
  22 + private static final String TOKEN_KEY = "Sec-WebSocket-Protocol";
  23 +
  24 + private static CommonAPI commonApi;
  25 +
  26 + private static RedisUtil redisUtil;
  27 +
  28 + @Override
  29 + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  30 + if (commonApi == null) {
  31 + commonApi = SpringContextUtils.getBean(CommonAPI.class);
  32 + }
  33 + if (redisUtil == null) {
  34 + redisUtil = SpringContextUtils.getBean(RedisUtil.class);
  35 + }
  36 + HttpServletRequest request = (HttpServletRequest)servletRequest;
  37 + String token = request.getHeader(TOKEN_KEY);
  38 +
  39 + log.info("websocket连接 Token安全校验,Path = {},token:{}", request.getRequestURI(), token);
  40 +
  41 + try {
  42 + TokenUtils.verifyToken(token, commonApi, redisUtil);
  43 + } catch (Exception exception) {
  44 + log.error("websocket连接校验失败,{},token:{}", exception.getMessage(), token);
  45 + return;
  46 + }
  47 + HttpServletResponse response = (HttpServletResponse)servletResponse;
  48 + response.setHeader(TOKEN_KEY, token);
  49 + filterChain.doFilter(servletRequest, servletResponse);
  50 + }
  51 +
  52 +}
... ...