java里面拦截器

@WebFilter({"/*"})
package com.sf.gis.boot.filter;

import com.alibaba.fastjson.JSON;
import com.sf.gis.common.constants.CommonConstant;
import com.sf.gis.common.domain.vo.user.TokenInfoVo;
import com.sf.gis.common.utils.JWTUtil;
import com.sf.gis.common.utils.TokenThreadLocal;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@WebFilter({"/*"})
public class CheckTokenFilter implements Filter {

    @Value("${check.white-list}")
    private String whiteList;
    @Value("${jwt.thirdparty_key}")
    private String thirdpartyKey;
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
        httpServletResponse.setContentType("application/json;charset=utf-8");

        String url = httpServletRequest.getRequestURI();
        boolean match = filterPath(url);
        if (match) {
            log.info("白名单直接放行url={}", url);
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        String token = httpServletRequest.getHeader(CommonConstant.TOKEN);
        String authModel = httpServletRequest.getHeader(CommonConstant.TOKEN_MODEL);
        //没有token
        if (!StringUtils.hasLength(token)) {
            Map<String, String> map = new HashMap<>();
            map.put("code", "401");
            map.put("msg", "请先登录");
            log.error("token-check: tokenInfoVo no have token: url: {}", url);
            String string = JSON.toJSONString(map);
            httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
            httpServletResponse.getWriter().write(string);
            return;
        }

        //判断token是否过期
        TokenInfoVo tokenInfoVo = null;
        boolean flag = false;
        try {
            // 第三方鉴权: header请求头中添加 x-auth-model 参数并且只为2 表示第三方请求,按照第三方的秘钥加解密token
            if("2".equals(authModel) && org.apache.commons.lang3.StringUtils.isNotBlank(thirdpartyKey)) {
                tokenInfoVo = JWTUtil.getJWTUtil().parseToken(token,thirdpartyKey);
            } else {
                tokenInfoVo = JWTUtil.getJWTUtil().parseToken(token);
            }
            Long exp = Long.valueOf(tokenInfoVo.getExp());
            log.error("token-check: tokenInfoVo.getExp 过期时间:exp: {}, url: {}, token: {}", exp, url, token);
            long nowTime = System.currentTimeMillis() / 1000;
            log.error("token-check: tokenInfoVo.getExp nowTime:exp: {}, url: {}, token: {}", nowTime, url, token);
            if (exp < nowTime) {
                flag = true;
                log.error("token-check: false-tokenInfoVo.getExp exp <= nowTime:true, url:{}, token:{}", url, token);
            }
        } catch (Exception e) {
            flag = true;
            log.error("token-check: false-token解析失败:url:{},token:{}", url, token, e);
        }
        if (flag) {
            Map<String, String> map = new HashMap<>();
            map.put("code", "401");
            map.put("msg", "token不存在或已过期");
            String string = JSON.toJSONString(map);
            log.error("token-check: false-tokenInfoVo parse error:url:{},token:{}", url, token);
            httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
            httpServletResponse.getWriter().write(string);
            return;
        }
        TokenThreadLocal.set(token);
        try {
            filterChain.doFilter(servletRequest, servletResponse);
        } finally {
            TokenThreadLocal.remove();
        }
    }

    /**
     * 校验路径
     */
    private boolean filterPath(String url) {
        AntPathMatcher pathMatcher = new AntPathMatcher();
        pathMatcher.setCaseSensitive(false);
        String[] ignoredUrls= whiteList.split(",");

        boolean flag = false;
        for (String ignoredUrl : ignoredUrls) {
            flag = pathMatcher.match(ignoredUrl, url);
            if (flag) {
                break;
            }
        }
        return flag;
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

package com.sf.gis.boot.filter;

import cn.hutool.core.util.StrUtil;
import com.sf.gis.common.constants.CommonConstant;
import com.sf.gis.common.domain.vo.user.TokenInfoVo;
import com.sf.gis.common.utils.JWTUtil;
import com.sf.gis.common.utils.TokenThreadLocal;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
@WebFilter({"/*"})
public class RefreshTokenFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;

        String url = httpServletRequest.getRequestURI();
        //判断token是否即将过期:过期时间 - 当前时间 <= 15分钟
        int interval = 15;
        String token = httpServletRequest.getHeader(CommonConstant.TOKEN);
        if (StrUtil.isNotBlank(token) && !"null".equals(token)) {
            TokenInfoVo tokenInfoVo = null;
            boolean isExpired = false;
            try {
                tokenInfoVo = JWTUtil.getJWTUtil().parseToken(token);
                Long exp = Long.valueOf(tokenInfoVo.getExp());
                long nowTime = System.currentTimeMillis() / 1000;
                if ((exp - nowTime) / 60 <= interval) {
                    isExpired = true;
                }
            } catch (Exception e) {
                isExpired = true;
                log.error("token-check:exp token解析失败, url:{}, token:{}", url, token, e);
            }
            //添加刷新标识
            if (isExpired) {
                log.error("token-check:exp tokenInfoVo parse error: url:{}, token:{}}", url, token);
                httpServletResponse.setHeader("x-refresh-token", "true");
            }

        }
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

package com.sf.gis.boot.filter;


import com.alibaba.fastjson.JSONObject;
import com.sf.gis.common.utils.SM4Utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;

/**
 * 过滤器拦截请求,实现对请求参数的解密功能
 */

@Slf4j
@Component
public class DecryptFilter implements Filter {
    //不需要加密的接口
    @Value("${req.ignoreDecryptUrl}")
    private String ignoreDecryptUrl;
    @Value("${res.encryptKey}")
    private String decryptKey;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        try {
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            RequestWrapper requestWrapper = new RequestWrapper((HttpServletRequest) request);
            String method = request.getMethod();
            String url = request.getRequestURI();
            log.info("请求参数的解密,请求路径={}", url);
            Boolean flag = false;
            String contentType = request.getContentType();
            /*if (StringUtils.isNotEmpty(contentType)
                    && contentType.contains("multipart/form-data")) {
                String contentDisposition = requestWrapper.getHeader("Content-Disposition");
                if (StringUtils.isNotBlank(contentDisposition)) {
                    log.info("上传文件Content-Disposition:{}", contentDisposition);
                }
                if (StringUtils.isNotBlank(contentType)) {
                    log.info("上传文件contentType:{}", contentType);
                }
                Enumeration<String> em = requestWrapper.getHeaderNames();
                while (em.hasMoreElements()) {
                    String str = em.nextElement();
                    if (StringUtils.isNotBlank(str)) {
                        String headerValue = requestWrapper.getHeader(str);
                        if (StringUtils.isNotBlank(headerValue)) {
                            log.info("上传文件headerName:{},headerValue:{}", str,headerValue);
                        }
                    }
                }
            }*/
            //判断是否是静态资源
            if (isStaticResource(url)) {
                flag = true;
            } else {
                url = url.split("\\?")[0];
                AntPathMatcher pathMatcher = new AntPathMatcher();
                pathMatcher.setCaseSensitive(false);
                String[] ignoredUrls = ignoreDecryptUrl.split(",");
                for (String ignoredUrl : ignoredUrls) {
                    flag = pathMatcher.match(ignoredUrl, url);
                    if (flag) {
                        break;
                    }
                }
            }
            if (!flag) {
                if (!"POST".equals(method)) {
                    response.setCharacterEncoding("UTF-8");
                    PrintWriter out = response.getWriter();
                    out.print("只允许使用POST请求方式");
                    out.flush();
                    out.close();
                }
                // 该方法处理 POST请求并且contentType为application/json格式的
                if ("POST".equals(method)
                        && StringUtils.isNotEmpty(contentType)
                        && contentType.contains(MediaType.APPLICATION_JSON_VALUE)) {
                    String str = new String(requestWrapper.getBody());
                    if (StringUtils.isNotBlank(str) && !"null".equals(str) && !"{}".equals(str)) {
                        JSONObject jsonObject = JSONObject.parseObject(str);
                        if (!jsonObject.containsKey("body")) {
                            response.setCharacterEncoding("UTF-8");
                            PrintWriter out = response.getWriter();
                            out.print("请求实体必须包含body,如:{\"body\":\"加密串\"}");
                            out.flush();
                            out.close();
                        } else {
                            if (null == jsonObject.get("body")) {
                                chain.doFilter(requestWrapper, response);
                            } else {
                                String bodyStr = jsonObject.get("body").toString();
                                if (StringUtils.isBlank(bodyStr)) {
                                    chain.doFilter(requestWrapper, response);
                                } else {
                                    //post请求内容需要解密
                                    str = SM4Utils.getsM4Utils().strDecode(bodyStr, decryptKey);
                                    requestWrapper.setBody(str.getBytes(StandardCharsets.UTF_8));
                                    chain.doFilter(requestWrapper, response);
                                }
                            }
                        }
                    } else {
                        // 继续处理请求
                        chain.doFilter(requestWrapper, response);
                    }
                } else {
                    // 继续处理请求
                    chain.doFilter(requestWrapper, response);
                }
            } else {
                chain.doFilter(requestWrapper, response);
            }
        } catch (Exception e) {
            log.error("DecryptFilter解密失败", e);
        }

    }

/*    private void setPostParameterMap(Map<String, String[]> decryptedParameterMap, String decryptedValues) {
        getJsonObject(decryptedParameterMap, decryptedValues);
    }

    private void getJsonObject(Map<String, String[]> decryptedParameterMap, String decryptedValues) {
        JSONObject jsonObject = JSONObject.parseObject(decryptedValues);
        if (Objects.nonNull(jsonObject)) {
            if (jsonObject.size() > 0) {
                String body = jsonObject.getString("body");
                if (body.startsWith("[")) {
                    String[] params = new String[1];
                    params[0] = body;
                    decryptedParameterMap.put("param", params);
                } else {
                    JSONObject parseObject = JSONObject.parseObject(body);
                    Set<String> strings = parseObject.keySet();
                    for (String string : strings) {
                        String[] params = new String[1];
                        params[0] = parseObject.getString(string);
                        //数组参数处理
                        if (params[0].contains("[")) {
                            String[] res = JSONObject.parseObject(params[0], String[].class);
                            decryptedParameterMap.put(string, res);
                        } else {
                            decryptedParameterMap.put(string, params);
                        }
                    }
                }
            }
        }

    }

    private void setParameterMap(Map<String, String[]> decryptedParameterMap, String decryptedValues) {
        getJsonObject(decryptedParameterMap, decryptedValues);
    }*/

    @Override
    public void destroy() {

    }


    private Set<String> staticResourceTypes = new HashSet<String>();

    {
        staticResourceTypes.add(".html");
        staticResourceTypes.add(".css");
        staticResourceTypes.add(".js");
        staticResourceTypes.add(".png");
        staticResourceTypes.add(".jpg");
        staticResourceTypes.add(".otf");
        staticResourceTypes.add(".eot");
        staticResourceTypes.add(".svg");
        staticResourceTypes.add(".ttf");
        staticResourceTypes.add(".woff");
        staticResourceTypes.add(".gif");
        staticResourceTypes.add(".ico");
        staticResourceTypes.add(".txt");
        staticResourceTypes.add(".gzip");
        staticResourceTypes.add(".xz");
        staticResourceTypes.add(".tar.gz");
        staticResourceTypes.add(".tar.bz2");
        staticResourceTypes.add(".jar");
        staticResourceTypes.add(".war");
        staticResourceTypes.add(".7z");
        staticResourceTypes.add(".tgz");
        staticResourceTypes.add(".gz");
        staticResourceTypes.add(".map");

    }

    public final boolean isStaticResource(String url) {

        boolean result = false;
        if (StringUtils.isBlank(url)) {
            return result;
        }
        int start = url.lastIndexOf(".");
        if (start < 0) {
            return result;
        }
        String prex = url.substring(start, url.length());
        return staticResourceTypes.contains(prex);
    }
}

package com.sf.gis.boot.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sf.gis.common.utils.SM4Utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;


/**
 * 过滤器拦截请求,实现接口响应数据加密功能
 *
 * @Component 将此Filter交给Spring容器管理
 * @WebFilter 通过WebFilter进行Filter声明,这样容器在进行部署的时候就会处理该Filter
 *
 */
@Slf4j
@Component
public class EncryptFilter implements Filter {
    @Value("${res.ignoreEncryptUrl}")
    private String ignoreEncryptUrl;
    @Value("${res.encryptKey}")
    private String encryptKey;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // TODO Auto-generated method stub
    }
    /**
     * 有错误相应返回-44
     *
     * @param response
     */
    private void getFailResponse(HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = null;
        out = response.getWriter();
        //加密后的错误消息
        out.write("服务器异常,接口返回值加密异常!");
        out.flush();
        out.close();
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        HttpServletRequest httpRequest=(HttpServletRequest)request;
        HttpServletResponse httpResponse=(HttpServletResponse)response;
        httpResponse.setCharacterEncoding("UTF-8");
        boolean flag=isIgnore2(httpRequest,ignoreEncryptUrl);
        if(flag || 200!=httpResponse.getStatus()) {
            try {
                chain.doFilter(request, httpResponse);
            } catch (Exception e) {
                log.error("EncryptFilter过滤器异常",e);
            }
        }else{
            try{
                //响应处理  包装响应对象 res 并缓存响应数据
                ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) response);
                //执行业务逻辑 交给下一个过滤器或servlet处理
                chain.doFilter(request, responseWrapper);
                byte[] resData = responseWrapper.getResponseData();
                String resStr=new String(resData);
                //把转成json,判断是否包含result节点,包含则对result里面的数据进行加密,否则原样返回
                JSONObject json=JSON.parseObject(resStr);
                if(json!=null && json.containsKey("result")){
                    Object item = json.get("result");
                    //先判断是不是Json串,如果不是的话
                    if(item == null){
                        chain.doFilter(request, responseWrapper);
                    }else{
                        if(!getJSONType(String.valueOf(item))){
                            json.put("result",SM4Utils.getsM4Utils().strEncode(String.valueOf(item),encryptKey));
                            handleOutPut((HttpServletResponse) response,json.toString());
                        }else{
                            String result="";
                            if(item instanceof JSONArray){
                                result=json.getJSONArray("result").toJSONString();
                            }else{
                                result=json.getJSONObject("result").toJSONString();
                            }
                            result=SM4Utils.getsM4Utils().strEncode(result,encryptKey);
                            json.put("result",result);
                            handleOutPut((HttpServletResponse) response,json.toString());
                        }

                    }

                }else{
                    handleOutPut((HttpServletResponse) response,resStr);
                }
            }catch(Exception e){
                try {
                    getFailResponse((HttpServletResponse)response);
                } catch (IOException ex) {
                    log.error("EncryptFilter过滤器处理接口返回值加密失败返回异常",e);
                }
                log.error("EncryptFilter过滤器处理接口返回值加密异常",e);
            }
        }
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }
    public static boolean getJSONType(String str) {
        boolean result = false;
        if (StringUtils.isNotBlank(str)) {
            str = str.trim();
            if (str.startsWith("{") && str.endsWith("}")) {
                result = true;
            } else if (str.startsWith("[") && str.endsWith("]")) {
                result = true;
            }
        }
        return result;
    }
    /**
     * 哪些路径不处理
     * @param request
     * @param
     * @return
     */
    public boolean isIgnore(HttpServletRequest request,String ignoreEncryptUrl) {
        if(StringUtils.isBlank(ignoreEncryptUrl)){
            return false;
        }
        String[] attr= ignoreEncryptUrl.split(",");
        String path=request.getRequestURI();
        for(String ignore:attr) {
            if(path.contains(ignore)) {
                return true;
            }
        }
        return false;
    }

    public boolean isIgnore2(HttpServletRequest request,String ignoreEncryptUrl) {
        if(StringUtils.isBlank(ignoreEncryptUrl)){
            return false;
        }
        String url=request.getRequestURI();
        url = url.split("\\?")[0];
        log.info("响应数据加密,请求路径={}",url);
        AntPathMatcher pathMatcher = new AntPathMatcher();
        pathMatcher.setCaseSensitive(false);
        String[] ignoredUrls=ignoreEncryptUrl.split(",");
        for (String ignoredUrl : ignoredUrls) {
           boolean flag = pathMatcher.match(ignoredUrl, url);
            if (flag) {
               return flag;
            }
        }
        return false;
    }
    private void handleOutPut(HttpServletResponse response,String resResult) throws Exception{
        PrintWriter out = response.getWriter();
        out.print(resResult);
        out.flush();
        out.close();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值