使用过滤器过滤请求参数中的敏感信息

上节已经介绍了过滤器的使用方法,现在我们来看下实际场景中,如何使用过滤器过滤请求的参数中的敏感信息,主要针对get、post两种请求方式过滤。

1. get请求参数过滤

get请求,可以从request中拿到请求参数,看参数中是否包含敏感信息,假设敏感信息是"傻瓜"

HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        boolean flag = true;
        String badInfo = "傻瓜";
        if (httpServletRequest.getMethod().equals(RequestMethod.GET.name())) {
            Map<String, String[]> parameterMap = httpServletRequest.getParameterMap();
            if (!MapUtils.isEmpty(parameterMap)) {
                flag =!parameterMap.entrySet().stream().anyMatch(entry -> Arrays.toString(entry.getValue()).contains(badInfo));
                if (!flag) {
                    servletResponse.setContentType("application/json; charset=UTF-8");
                    PrintWriter out = servletResponse.getWriter();
                    ResultResponse resultResponse = new ResultResponse();
                    out.println(JSON.toJSONString(ResultResponse.fail("-9999", "参数包含敏感信息")));
                    out.flush();
                } else {
                    filterChain.doFilter(servletRequest, servletResponse);
                }
            } else {
                filterChain.doFilter(servletRequest, servletResponse);
            }
        }

测试,访问一个get接口,参数为"笨蛋",结果如下

2. post请求参数过滤

post请求参数就不能直接获取了,要通过输入流InputStream获取,但是这里有一个坑

public String getParm(HttpServletRequest request) {
    BufferedReader br = null;
    try {
        br = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));
    } catch (IOException e) {
    }
    String line = null;
    StringBuilder sb = new StringBuilder();
    try {
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
    } catch (IOException e) {
    }
    return sb.toString();
}

这个方法就是从post请求中获取参数,参数可以正常获取,但是访问却会报错

错误说缺少请求体,但是我们明明有传参,可知从InputStream获取参数只能获取一次,因为InputStream内部有个pos指针,指向下次要读取的起始位置,由于已经读取了一次,指针位置已指向末端,ServletInputStream没有重写reset方法,无法重置pos指针指向位置,所以当读取完后将无法继续读取

因此我们可以请求参数以byte[]形式存起来,新建class继承HttpServletRequestWrapper

public class RequestWrapper extends HttpServletRequestWrapper {
    private String body;
    public RequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        try {
            InputStream inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"UTF-8"));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            } else {
                stringBuilder.append("");
            }
        } catch (IOException ex) {
            throw ex;
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException ex) {
                    throw ex;
                }
            }
        }
        body = stringBuilder.toString();
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
        ServletInputStream servletInputStream = new ServletInputStream() {
            public boolean isFinished() {
                return false;
            }
            public boolean isReady() {
                return false;
            }
            public void setReadListener(ReadListener readListener) {}
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
        return servletInputStream;

    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream(),"UTF-8"));
    }
    public String getBody() {
        return this.body;
    }
}

过滤器的doFilter方法如下

} else if (httpServletRequest.getMethod().equals(RequestMethod.POST.name())) {
            RequestWrapper requestWrapper = new RequestWrapper(httpServletRequest);
            if(requestWrapper == null) {
                filterChain.doFilter(servletRequest, servletResponse);
            } else {
                String body = requestWrapper.getBody();
                flag = !body.contains(badInfo);
                if (!flag) {
                    servletResponse.setContentType("application/json; charset=UTF-8");
                    PrintWriter out = servletResponse.getWriter();
                    ResultResponse resultResponse = new ResultResponse();
                    out.println(JSON.toJSONString(ResultResponse.fail("-9999"
                            , "参数包含敏感信息")));
                    out.flush();
                } else {
                    filterChain.doFilter(requestWrapper, servletResponse);
                }
            }
        } else {
            filterChain.doFilter(servletRequest, servletResponse);
        }

访问一个post接口,包含敏感信息’笨蛋’

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值