Springboot中如何使用過濾器校驗(yàn)PSOT類型請(qǐng)求參數(shù)內(nèi)容
目的
在Springboot中創(chuàng)建過濾器,用來(lái)過濾所有POST類型請(qǐng)求并獲取body中的參數(shù)進(jìn)行校驗(yàn)內(nèi)容是否合法;該方法僅適用于POST類型請(qǐng)求,因?yàn)镻OST和GET請(qǐng)求的參數(shù)位置不一樣所以處理方式也不一樣,如果想要實(shí)現(xiàn)攔截獲取GET類型請(qǐng)求校驗(yàn)參數(shù),可以參考以下示例:
Springboot中攔截GET請(qǐng)求獲取請(qǐng)求參數(shù)驗(yàn)證合法性
實(shí)現(xiàn)步驟
1、創(chuàng)建Filter過濾器用來(lái)過濾所有請(qǐng)求;
2、將PSOT類型請(qǐng)求中的body參數(shù)內(nèi)容進(jìn)行轉(zhuǎn)換;
3、處理body數(shù)據(jù)進(jìn)行校驗(yàn):
3.1、當(dāng)body數(shù)據(jù)僅為json對(duì)象時(shí)進(jìn)行處理校驗(yàn);
3.2、當(dāng)body數(shù)據(jù)僅為json數(shù)組時(shí)進(jìn)行處理校驗(yàn);
3.3、當(dāng)body數(shù)據(jù)為json對(duì)象且包含json數(shù)組時(shí)進(jìn)行處理校驗(yàn);
3.4、當(dāng)body數(shù)據(jù)為json數(shù)組且包含json對(duì)象時(shí)進(jìn)行處理校驗(yàn);
完整代碼
過濾器
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 過濾請(qǐng)求內(nèi)容 防止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對(duì)象 boolean b = resolveJSONObjectObj(requestPostStr); if (!b) { response.getWriter().print(data); return; } } else if (requestPostStr.startsWith("[")) { //把數(shù)據(jù)轉(zhuǎn)換成json數(shù)組 JSONArray jsonArray = JSONArray.parseArray(requestPostStr); List<String> list = JSONObject.parseArray(jsonArray.toJSONString(), String.class); for (String str : list) { if (str.startsWith("{")) { //解析json對(duì)象 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()) { //校驗(yàn)參數(shù)值是否合法 String[] value = entry.getValue(); for (String s : value) { //校驗(yàn)參數(shù)值是否合法 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: 對(duì)JSONObject對(duì)象進(jìn)行遞歸參數(shù)解析 * @DateTime: 14:26 2023/8/9 * @Params: * @Return */ private boolean resolveJSONObjectObj(String requestPostStr) { boolean isover = true; // 創(chuàng)建需要處理的json對(duì)象 JSONObject jsonObject = JSONObject.parseObject(requestPostStr); // 獲取所有的參數(shù)key Set<String> keys = jsonObject.keySet(); if (keys.size() > 0) { for (String key : keys) { //獲取參數(shù)名稱 String value; if (jsonObject.get(key) != null) { value = String.valueOf(jsonObject.get(key)); //當(dāng)value為數(shù)組時(shí) if (value.startsWith("[")) { //把數(shù)據(jù)轉(zhuǎn)換成json數(shù)組 JSONArray jsonArray = JSONArray.parseArray(value); for (Object o : jsonArray) { if (o.toString().startsWith("{")) { //解析json對(duì)象 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 { //校驗(yàn)參數(shù)值是否合法 boolean b = verifySql(value); if (b) { isover = false; break; } } } } } return isover; } @Override public void destroy() { } /** * @Author: ljh * @Description: 校驗(yàn)參數(shù)非法字符 * @DateTime: 14:26 2023/8/9 * @Params: * @Return */ public boolean verifySql(String parameter) { String s = parameter.toLowerCase(); // 過濾掉的sql關(guān)鍵字,特殊字符前面需要加\\進(jìn)行轉(zhuǎn)義 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|" + "'\\*|\\;|\\-|\\--|\\+|\\,|\\//|\\/|\\%|\\#"; //使用正則表達(dá)式進(jìn)行匹配 boolean matches = s.matches(badStr); return matches; } }
解析body數(shù)據(jù) 工具類
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數(shù)據(jù) * @date 2023/8/8 16:14 * @Version 1.0 */ public class BodyReaderRequestWrapper extends HttpServletRequestWrapper { private final String body; public String getBody() { return body; } /** * 取出請(qǐng)求體body中的參數(shù)(創(chuàng)建對(duì)象時(shí)執(zhí)行) * * @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(); } }; } }
到此這篇關(guān)于Springboot中如何使用過濾器校驗(yàn)PSOT類型請(qǐng)求參數(shù)內(nèi)容的文章就介紹到這了,更多相關(guān)Springboot校驗(yàn)PSOT請(qǐng)求參數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot常見get/post請(qǐng)求參數(shù)處理、參數(shù)注解校驗(yàn)及參數(shù)自定義注解校驗(yàn)詳解
- SpringBoot 如何自定義請(qǐng)求參數(shù)校驗(yàn)
- springboot整合JSR303參數(shù)校驗(yàn)與全局異常處理的方法
- springboot接口參數(shù)校驗(yàn)JSR303的實(shí)現(xiàn)
- SpringBoot使用jsr303校驗(yàn)的實(shí)現(xiàn)
- Springboot集成JSR303參數(shù)校驗(yàn)的方法實(shí)現(xiàn)
- Spring Boot中使用JSR-303實(shí)現(xiàn)請(qǐng)求參數(shù)校驗(yàn)
相關(guān)文章
Java設(shè)計(jì)模塊系列之書店管理系統(tǒng)單機(jī)版(二)
這篇文章主要為大家詳細(xì)介紹了Java單機(jī)版的書店管理系統(tǒng)設(shè)計(jì)模塊和思想第二章,感興趣的小伙伴們可以參考一下2016-08-08關(guān)于IDEA配置Hibernate中遇到的問題解決
這篇文章主要給大家介紹了關(guān)于IDEA配置Hibernate中遇到的問題,文中通過圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05圖解Java經(jīng)典算法冒泡選擇插入希爾排序的原理與實(shí)現(xiàn)
冒泡排序是一種簡(jiǎn)單的排序算法,它也是一種穩(wěn)定排序算法。其實(shí)現(xiàn)原理是重復(fù)掃描待排序序列,并比較每一對(duì)相鄰的元素,當(dāng)該對(duì)元素順序不正確時(shí)進(jìn)行交換。一直重復(fù)這個(gè)過程,直到?jīng)]有任何兩個(gè)相鄰元素可以交換,就表明完成了排序2022-09-09SpringBoot使用thymeleaf實(shí)現(xiàn)前端表格
雖然現(xiàn)在流行前后端分離,但是后端模版在一些關(guān)鍵地方還是非常有用的,例如郵件模版、代碼模版等。當(dāng)然也不排除一些古老的項(xiàng)目后端依然使用動(dòng)態(tài)模版。Thymeleaf 簡(jiǎn)潔漂亮、容易理解,并且完美支持 HTML5,可以直接打開靜態(tài)頁(yè)面,同時(shí)不新增標(biāo)簽,只需增強(qiáng)屬性2022-10-10Java優(yōu)雅的處理金錢問題(BigDecimal)
本文主要介紹了Java優(yōu)雅的處理金錢問題(BigDecimal),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06Java實(shí)現(xiàn)的二叉樹常用操作【前序建樹,前中后遞歸非遞歸遍歷及層序遍歷】
這篇文章主要介紹了Java實(shí)現(xiàn)的二叉樹常用操作,包括二叉樹的前序建樹,前中后遞歸非遞歸遍歷及層序遍歷等相關(guān)操作技巧,需要的朋友可以參考下2018-01-01