若依前后端分离版-服务端过滤器对POST请求参数解密(针对指定接口)+添加请求头

一、过滤器中对指定接口进行加密

去除指定接口验证的话,将会是对所有接口请求参数进行解密。

1、找到项目中的过滤器:RepeatableFilter

过滤器中的RepeatedlyRequestWrapper对POST请求参数数据允许可重复读取

2、下面对 RepeatedlyRequestWrapper进行改造(数据进行解密)或者自行创建一个新的xxxxRequestWrapper类替换掉RepeatableFilter中的RepeatedlyRequestWrapper

可添加请求头

/**
 * 构建可重复读取inputStream的request
 * 
 * @author ruoyi
 */
public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper
{
    private static final Logger log = LoggerFactory.getLogger(RepeatedlyRequestWrapper.class);

    // 重新赋值的body数据
    private String bodyJsonStr;

    // 重新赋值的请求头
    private Map<String, String> headerMap = new HashMap<>();

    //接口请求参数加密白名单
    public static List<String> encryptApi;

    static {//请求参数需加密的接口
        List<String> list = new ArrayList<String>();
        list.add("xxxxx/xxxxx/xxxxx");
        list.add("xxxxx/xxxxx/xxxxx");

        encryptApi = list;
    }

    public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException
    {
        super(request);
        request.setCharacterEncoding(Constants.UTF8);
        response.setCharacterEncoding(Constants.UTF8);

        //数据进行解密
        String shuju = preamerJiemi(request);

        this.bodyJsonStr = shuju;
    }

    //参数解密
    public String preamerJiemi(HttpServletRequest request){

        //获取请求路径(接口)
        StringBuffer url = request.getRequestURL();
        System.out.println(url);

        String shuju = null;
        if(getBoolenStatus(url.toString())){//验证接口是否需要对请求参数解密
            //获取请求参数
            String requestData = readBodyBytes(request);
            JSONObject jsonData = JSONObject.parseObject(requestData);
            String data = jsonData.getString("xxxxx");//获取加密数据

            if(StringUtils.isBlank(data)){
                log.error("请求参数xxxxx加密数据不存在");
                throw new ServiceException("请求参数xxxxx不存在");
            }

            try {
                //对data数据进行解密(解密工具类请自行替换,需与客户端加密方式保持一致)
                shuju = AES128Util.decryptAES(data,AES128Util.keyIvJson);
                
                //请求头中添加数据(无此需求可去除)
                if(StringUtils.isBlank(getHeader("xxxxx"))){
                    //请求头中添加数据
                    addHeader("xxxxx", "xxxxx");
                }
            }catch (Exception e){
                log.error("解密失败:{}",e.getMessage());
                throw new ServiceException("解密失败,请联系客服");
            }
        }else{
            shuju = readBodyBytes(request);
        }

        return shuju;
    }

    //验证请求接口是否加入请求参数白名单
    public boolean getBoolenStatus(String requestURL){
        if(encryptApi != null && encryptApi.size() > 0){
            for(String list:encryptApi){
                if(requestURL.contains(list)){
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        if(StringUtils.isEmpty(bodyJsonStr)) {
            bodyJsonStr = "";
        }
        // 必须指定utf-8编码,否则json请求数据中如果包含中文,会出现异常
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bodyJsonStr.getBytes("utf-8"));
        ServletInputStream servletInputStream = new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }
            @Override
            public boolean isReady() {
                return false;
            }
            @Override
            public void setReadListener(ReadListener readListener) {
            }
            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
        return servletInputStream;
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }

    public String getBodyJsonStr() {
        return bodyJsonStr;
    }

    public void setBodyJsonStr(String bodyJsonStr) {
        this.bodyJsonStr = bodyJsonStr;
    }


    /**
     * add a header with given name and value
     *
     * @param name
     * @param value
     */
    public void addHeader(String name, String value) {
        headerMap.put(name, value);
    }

    @Override
    public String getHeader(String name) {
        log.info("getHeader --->{}",name);
        String headerValue = super.getHeader(name);
        if (headerMap.containsKey(name)) {
            headerValue = headerMap.get(name);
        }
        return headerValue;
    }

    /**
     * get the Header names
     */
    @Override
    public Enumeration<String> getHeaderNames() {
        List<String> names = Collections.list(super.getHeaderNames());
        for (String name : headerMap.keySet()) {
            names.add(name);
        }
        return Collections.enumeration(names);
    }

    @Override
    public Enumeration<String> getHeaders(String name) {
        List<String> values = Collections.list(super.getHeaders(name));
        if (headerMap.containsKey(name)) {
            values = Arrays.asList(headerMap.get(name));
        }
        return Collections.enumeration(values);
    }

    //获取请求体中的JSON格式参数
    private String readBodyBytes(HttpServletRequest request) {

        String bodyContent = null;
        try {
            byte[] bodyBytes = readInputBody(request.getInputStream());
            bodyContent = new String(bodyBytes, Constants.UTF8);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return bodyContent;
    }

    private byte[] readInputBody(InputStream inputStream) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        while ((len = inputStream.read(buffer)) > -1) {
            byteArrayOutputStream.write(buffer, 0, len);
        }
        byteArrayOutputStream.flush();
        return byteArrayOutputStream.toByteArray();
    }
}

到此就结束了。

以下为参考文章:

HttpServletRequest修改header值_httpservletrequest 设置header_thulium_的博客-CSDN博客

重写Request,修改Request中的Body内容 - 简书

前后端分离数据传输加解密方案(建议方案二)_前后端分离密码加密解决方案_zengliangxi的博客-CSDN博客

 获取所有请求参数(Map的形式返回):

	public static Map getRequestParamMap(HttpServletRequest request)
	{
		Map map = new HashMap(); 
		//得到枚举类型的参数名称,参数名称若有重复的只能得到第一个 
		Enumeration enums = request.getParameterNames(); 
	    while (enums.hasMoreElements()) 
	    { 
		    String paramName = (String) enums.nextElement(); 
		    String paramValue = request.getParameter(paramName); 
	
		    //形成键值对应的map 
		    map.put(paramName, paramValue); 
	    }
		return map;
	}

猜你喜欢

转载自blog.csdn.net/yyongsheng/article/details/131676290
今日推荐