Springboot中如何使用過濾器校驗(yàn)PSOT類型請(qǐng)求參數(shù)內(nèi)容
目的
在Springboot中創(chuàng)建過濾器,用來過濾所有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過濾器用來過濾所有請(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)文章
idea SpringBoot+Gradle環(huán)境配置到項(xiàng)目打包
Gradle是一個(gè)基于Java應(yīng)用的項(xiàng)目自動(dòng)化構(gòu)建工具,本文介紹了在IDEA中創(chuàng)建Spring Boot Gradle項(xiàng)目,項(xiàng)目配置包括init.gradle和settings.gradle,感興趣的可以了解一下2024-11-11
Java Swing中的文本區(qū)(JTextArea)實(shí)現(xiàn)換行保存到文件的幾個(gè)方法
這篇文章主要介紹了Java Swing中的文本區(qū)(JTextArea)實(shí)現(xiàn)換行保存到文件的幾個(gè)方法,本文給出了4種方法,需要的朋友可以參考下2014-10-10
Java使用bcrypt實(shí)現(xiàn)對(duì)密碼加密效果詳解
bcrypt是一種自帶鹽值(自動(dòng)加鹽)的加密方案。本文將通過示例為大家詳細(xì)介紹這一對(duì)密碼進(jìn)行加密的算法,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-03-03
mybatis/mybatis-plus模糊查詢語句特殊字符轉(zhuǎn)義攔截器的實(shí)現(xiàn)
在開發(fā)中,我們通常會(huì)遇到這樣的情況。用戶在錄入信息是錄入了‘%’,而在查詢時(shí)無法精確匹配‘%’。究其原因,‘%’是MySQL的關(guān)鍵字,如果我們想要精確匹配‘%’,那么需要對(duì)其進(jìn)行轉(zhuǎn)義,本文就詳細(xì)的介紹一下2021-11-11
Spring Boot從打包到監(jiān)控的全鏈路實(shí)戰(zhàn)指南
本文系統(tǒng)講解了SpringBoot項(xiàng)目的打包方式(Jar/War)、部署方法(本地/服務(wù)器/Docker)及全鏈路監(jiān)控方案,涵蓋Actuator健康檢查、Prometheus指標(biāo)采集與Grafana可視化監(jiān)控,并介紹了如何通過Jenkins實(shí)現(xiàn)自動(dòng)化部署,感興趣的朋友跟隨小編一起看看吧2025-09-09
Java switch()括號(hào)內(nèi)參數(shù)的類型要求詳解
這篇文章主要介紹了Java switch()括號(hào)內(nèi)參數(shù)的類型要求,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
Struts2單選按鈕詳解及枚舉類型的轉(zhuǎn)換代碼示例
這篇文章主要介紹了Struts2單選按鈕詳解及枚舉類型的轉(zhuǎn)換代碼示例,分享了相關(guān)代碼示例,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-02-02

