Springboot中如何使用过滤器校验PSOT类型请求参数内容
目的
在Springboot中创建过滤器,用来过滤所有POST类型请求并获取body中的参数进行校验内容是否合法;该方法仅适用于POST类型请求,因为POST和GET请求的参数位置不一样所以处理方式也不一样,如果想要实现拦截获取GET类型请求校验参数,可以参考以下示例:
实现步骤
1、创建Filter过滤器用来过滤所有请求;
2、将PSOT类型请求中的body参数内容进行转换;
3、处理body数据进行校验:
3.1、当body数据仅为json对象时进行处理校验;
3.2、当body数据仅为json数组时进行处理校验;
3.3、当body数据为json对象且包含json数组时进行处理校验;
3.4、当body数据为json数组且包含json对象时进行处理校验;
完整代码
过滤器
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.boc.ljh.utils.Result; import com.boc.ljh.utils.status.AppErrorCode; import org.springframework.context.annotation.Configuration; 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.List; import java.util.Map; import java.util.Set; /** * @Author: ljh * @ClassName SqlFilter * @Description 过滤请求内容 防止sql注入 * @date 2023/8/8 16:15 * @Version 1.0 */ @WebFilter(urlPatterns = "/*", filterName = "sqlFilter") @Configuration public class SqlFilter implements Filter { @Override public void init(FilterConfig filterConfig) { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) servletResponse; response.setContentType("application/json;charset=utf-8"); Result result = new Result(); result.setStatus(500); result.setMessage(AppErrorCode.REQUEST_DATA_FULL.message); String data = JSON.toJSONString(result); BodyReaderRequestWrapper wrapper = null; HttpServletRequest request = (HttpServletRequest) servletRequest; if (request.getMethod().equals("POST")) { String contentType = request.getContentType(); if ("application/json".equals(contentType)) { wrapper = new BodyReaderRequestWrapper(request); String requestPostStr = wrapper.getBody(); if (requestPostStr.startsWith("{")) { //解析json对象 boolean b = resolveJSONObjectObj(requestPostStr); if (!b) { response.getWriter().print(data); return; } } else if (requestPostStr.startsWith("[")) { //把数据转换成json数组 JSONArray jsonArray = JSONArray.parseArray(requestPostStr); List<String> list = JSONObject.parseArray(jsonArray.toJSONString(), String.class); for (String str : list) { if (str.startsWith("{")) { //解析json对象 boolean b = resolveJSONObjectObj(requestPostStr); if (!b) { response.getWriter().print(data); return; } } else { boolean b = verifySql(str); if (b) { try { response.getWriter().print(data); return; } catch (IOException e) { e.printStackTrace(); } } } } } } else { //application/x-www-form-urlencoded Map<String, String[]> parameterMap = request.getParameterMap(); for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) { //校验参数值是否合法 String[] value = entry.getValue(); for (String s : value) { //校验参数值是否合法 boolean b = verifySql(s); if (b) { response.getWriter().print(data); return; } } } } } if (wrapper == null) { filterChain.doFilter(servletRequest, servletResponse); } else { filterChain.doFilter(wrapper, servletResponse); } } /** * @Author: ljh * @Description: 对JSONObject对象进行递归参数解析 * @DateTime: 14:26 2023/8/9 * @Params: * @Return */ private boolean resolveJSONObjectObj(String requestPostStr) { boolean isover = true; // 创建需要处理的json对象 JSONObject jsonObject = JSONObject.parseObject(requestPostStr); // 获取所有的参数key Set<String> keys = jsonObject.keySet(); if (keys.size() > 0) { for (String key : keys) { //获取参数名称 String value; if (jsonObject.get(key) != null) { value = String.valueOf(jsonObject.get(key)); //当value为数组时 if (value.startsWith("[")) { //把数据转换成json数组 JSONArray jsonArray = JSONArray.parseArray(value); for (Object o : jsonArray) { if (o.toString().startsWith("{")) { //解析json对象 boolean b = resolveJSONObjectObj(o.toString()); if (!b) { isover = false; break; } } else { boolean b = verifySql(value); if (b) { isover = false; break; } } } } else if (value.startsWith("{")) { boolean b = resolveJSONObjectObj(value); if (!b) { isover = false; break; } } else { //校验参数值是否合法 boolean b = verifySql(value); if (b) { isover = false; break; } } } } } return isover; } @Override public void destroy() { } /** * @Author: ljh * @Description: 校验参数非法字符 * @DateTime: 14:26 2023/8/9 * @Params: * @Return */ public boolean verifySql(String parameter) { String s = parameter.toLowerCase(); // 过滤掉的sql关键字,特殊字符前面需要加\\进行转义 String badStr = "select|update|and|or|delete|insert|truncate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute|table|" + "char|declare|sitename|xp_cmdshell|like|from|grant|use|group_concat|column_name|" + "information_schema.columns|table_schema|union|where|order|by|" + "'\\*|\\;|\\-|\\--|\\+|\\,|\\//|\\/|\\%|\\#"; //使用正则表达式进行匹配 boolean matches = s.matches(badStr); return matches; } }
解析body数据 工具类
import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.*; /** * @Author: ljh * @ClassName BodyReaderRequestWrapper * @Description 解析body数据 * @date 2023/8/8 16:14 * @Version 1.0 */ public class BodyReaderRequestWrapper extends HttpServletRequestWrapper { private final String body; public String getBody() { return body; } /** * 取出请求体body中的参数(创建对象时执行) * * @param request */ public BodyReaderRequestWrapper(HttpServletRequest request) throws IOException { super(request); StringBuilder sb = new StringBuilder(); InputStream ins = request.getInputStream(); BufferedReader isr = null; try { if (ins != null) { isr = new BufferedReader(new InputStreamReader(ins)); char[] charBuffer = new char[128]; int readCount; while ((readCount = isr.read(charBuffer)) != -1) { sb.append(charBuffer, 0, readCount); } } } finally { if (isr != null) { isr.close(); } } sb.toString(); body = sb.toString(); } @Override public BufferedReader getReader() { return new BufferedReader(new InputStreamReader(this.getInputStream())); } @Override public ServletInputStream getInputStream() { final ByteArrayInputStream byteArrayIns = new ByteArrayInputStream(body.getBytes()); return new ServletInputStream() { @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener readListener) { } @Override public int read() { return byteArrayIns.read(); } }; } }
到此这篇关于Springboot中如何使用过滤器校验PSOT类型请求参数内容的文章就介绍到这了,更多相关Springboot校验PSOT请求参数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Java基于装饰者模式实现的图片工具类实例【附demo源码下载】
这篇文章主要介绍了Java基于装饰者模式实现的图片工具类,结合完整实例形式分析了装饰者模式实现图片的判断、水印、缩放、复制等功能,并附带demo源码供读者下载参考,需要的朋友可以参考下2017-09-09idea Maven 插件 docker-maven-plugin 打包docker镜像上传到远程仓库的过程详解
这篇文章主要介绍了idea Maven插件docker-maven-plugin打包docker镜像上传到远程仓库,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2023-05-05解决@Test注解在Maven工程的Test.class类中无法使用的问题
这篇文章主要介绍了解决@Test注解在Maven工程的Test.class类中无法使用的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-03-03
最新评论