打个合并补丁
This commit is contained in:
parent
240d778fc2
commit
5d3fc49ef8
@ -1,15 +1,23 @@
|
|||||||
package com.ruoyi.common.utils.sql;
|
package com.ruoyi.common.utils.sql;
|
||||||
|
|
||||||
|
import java.io.StringReader;
|
||||||
|
|
||||||
import com.ruoyi.common.exception.UtilException;
|
import com.ruoyi.common.exception.UtilException;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
|
||||||
|
import net.sf.jsqlparser.JSQLParserException;
|
||||||
|
import net.sf.jsqlparser.parser.CCJSqlParserManager;
|
||||||
|
import net.sf.jsqlparser.statement.Statement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sql操作工具类
|
* sql操作工具类
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
public class SqlUtil
|
public class SqlUtil {
|
||||||
{
|
|
||||||
|
private static final CCJSqlParserManager parserManager = new CCJSqlParserManager();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定义常用的 sql关键字
|
* 定义常用的 sql关键字
|
||||||
*/
|
*/
|
||||||
@ -23,10 +31,8 @@ public class SqlUtil
|
|||||||
/**
|
/**
|
||||||
* 检查字符,防止注入绕过
|
* 检查字符,防止注入绕过
|
||||||
*/
|
*/
|
||||||
public static String escapeOrderBySql(String value)
|
public static String escapeOrderBySql(String value) {
|
||||||
{
|
if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) {
|
||||||
if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value))
|
|
||||||
{
|
|
||||||
throw new UtilException("参数不符合规范,不能进行查询");
|
throw new UtilException("参数不符合规范,不能进行查询");
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
@ -35,27 +41,26 @@ public class SqlUtil
|
|||||||
/**
|
/**
|
||||||
* 验证 order by 语法是否符合规范
|
* 验证 order by 语法是否符合规范
|
||||||
*/
|
*/
|
||||||
public static boolean isValidOrderBySql(String value)
|
public static boolean isValidOrderBySql(String value) {
|
||||||
{
|
|
||||||
return value.matches(SQL_PATTERN);
|
return value.matches(SQL_PATTERN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SQL关键字检查
|
* SQL关键字检查
|
||||||
*/
|
*/
|
||||||
public static void filterKeyword(String value)
|
public static void filterKeyword(String value) {
|
||||||
{
|
if (StringUtils.isEmpty(value)) {
|
||||||
if (StringUtils.isEmpty(value))
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
|
String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
|
||||||
for (String sqlKeyword : sqlKeywords)
|
for (String sqlKeyword : sqlKeywords) {
|
||||||
{
|
if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1) {
|
||||||
if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1)
|
|
||||||
{
|
|
||||||
throw new UtilException("参数存在SQL注入风险");
|
throw new UtilException("参数存在SQL注入风险");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Statement parseSql(String sql) throws JSQLParserException {
|
||||||
|
return parserManager.parse(new StringReader(sql));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,129 +0,0 @@
|
|||||||
package com.ruoyi.mybatisinterceptor.mybatis;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import com.ruoyi.mybatisinterceptor.annotation.MybatisHandlerOrder;
|
|
||||||
import com.ruoyi.mybatisinterceptor.sql.MybatisAfterHandler;
|
|
||||||
import com.ruoyi.mybatisinterceptor.sql.MybatisPreHandler;
|
|
||||||
import org.apache.ibatis.cache.CacheKey;
|
|
||||||
import org.apache.ibatis.executor.Executor;
|
|
||||||
import org.apache.ibatis.mapping.BoundSql;
|
|
||||||
import org.apache.ibatis.mapping.MappedStatement;
|
|
||||||
import org.apache.ibatis.plugin.Interceptor;
|
|
||||||
import org.apache.ibatis.plugin.Intercepts;
|
|
||||||
import org.apache.ibatis.plugin.Invocation;
|
|
||||||
import org.apache.ibatis.plugin.Signature;
|
|
||||||
import org.apache.ibatis.session.ResultHandler;
|
|
||||||
import org.apache.ibatis.session.RowBounds;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import jakarta.annotation.PostConstruct;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
@Intercepts({
|
|
||||||
@Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class,
|
|
||||||
RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class }),
|
|
||||||
@Signature(type = Executor.class, method = "query", args = {
|
|
||||||
MappedStatement.class, Object.class, RowBounds.class,
|
|
||||||
ResultHandler.class })
|
|
||||||
|
|
||||||
})
|
|
||||||
public class MybatisInterceptor implements Interceptor {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private List<MybatisPreHandler> preHandlerBeans;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private List<MybatisAfterHandler> afterHandlerBeans;
|
|
||||||
|
|
||||||
private static List<MybatisPreHandler> preHandlersChain;
|
|
||||||
|
|
||||||
private static List<MybatisAfterHandler> afterHandlersChain;
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void init() {
|
|
||||||
List<MybatisPreHandler> sortedPreHandlers = preHandlerBeans.stream().sorted((item1, item2) -> {
|
|
||||||
int a;
|
|
||||||
int b;
|
|
||||||
MybatisHandlerOrder ann1 = item1.getClass().getAnnotation(MybatisHandlerOrder.class);
|
|
||||||
MybatisHandlerOrder ann2 = item2.getClass().getAnnotation(MybatisHandlerOrder.class);
|
|
||||||
if (ann1 == null) {
|
|
||||||
a = 0;
|
|
||||||
} else {
|
|
||||||
a = ann1.value();
|
|
||||||
}
|
|
||||||
if (ann2 == null) {
|
|
||||||
b = 0;
|
|
||||||
} else {
|
|
||||||
b = ann2.value();
|
|
||||||
}
|
|
||||||
return a - b;
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
preHandlersChain = sortedPreHandlers;
|
|
||||||
|
|
||||||
List<MybatisAfterHandler> sortedAfterHandlers = afterHandlerBeans.stream().sorted((item1, item2) -> {
|
|
||||||
int a;
|
|
||||||
int b;
|
|
||||||
MybatisHandlerOrder ann1 = item1.getClass().getAnnotation(MybatisHandlerOrder.class);
|
|
||||||
MybatisHandlerOrder ann2 = item2.getClass().getAnnotation(MybatisHandlerOrder.class);
|
|
||||||
if (ann1 == null) {
|
|
||||||
a = 0;
|
|
||||||
} else {
|
|
||||||
a = ann1.value();
|
|
||||||
}
|
|
||||||
if (ann2 == null) {
|
|
||||||
b = 0;
|
|
||||||
} else {
|
|
||||||
b = ann2.value();
|
|
||||||
}
|
|
||||||
return a - b;
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
afterHandlersChain = sortedAfterHandlers;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object intercept(Invocation invocation) throws Throwable {
|
|
||||||
Executor targetExecutor = (Executor) invocation.getTarget();
|
|
||||||
Object[] args = invocation.getArgs();
|
|
||||||
if (args.length < 6) {
|
|
||||||
if (preHandlersChain != null && preHandlersChain.size() > 0) {
|
|
||||||
MappedStatement ms = (MappedStatement) args[0];
|
|
||||||
Object parameterObject = args[1];
|
|
||||||
RowBounds rowBounds = (RowBounds) args[2];
|
|
||||||
Executor executor = (Executor) invocation.getTarget();
|
|
||||||
BoundSql boundSql = ms.getBoundSql(parameterObject);
|
|
||||||
// 可以对参数做各种处理
|
|
||||||
CacheKey cacheKey = executor.createCacheKey(ms, parameterObject, rowBounds, boundSql);
|
|
||||||
for (MybatisPreHandler item : preHandlersChain) {
|
|
||||||
item.preHandle(targetExecutor, ms, args[1], (RowBounds) args[2],
|
|
||||||
(ResultHandler) args[3], cacheKey, boundSql);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Object result = invocation.proceed();
|
|
||||||
if (afterHandlersChain != null && afterHandlersChain.size() > 0) {
|
|
||||||
for (MybatisAfterHandler item : afterHandlersChain) {
|
|
||||||
item.handleObject(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if (preHandlersChain != null && preHandlersChain.size() > 0) {
|
|
||||||
for (MybatisPreHandler item : preHandlersChain) {
|
|
||||||
item.preHandle(targetExecutor, (MappedStatement) args[0], args[1], (RowBounds) args[2],
|
|
||||||
(ResultHandler) args[3], (CacheKey) args[4], (BoundSql) args[5]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Object result = invocation.proceed();
|
|
||||||
if (afterHandlersChain != null && afterHandlersChain.size() > 0) {
|
|
||||||
for (MybatisAfterHandler item : afterHandlersChain) {
|
|
||||||
result = item.handleObject(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -6,10 +6,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.ruoyi.mybatisinterceptor.annotation.MybatisHandlerOrder;
|
|
||||||
import com.ruoyi.mybatisinterceptor.context.page.PageContextHolder;
|
|
||||||
import com.ruoyi.mybatisinterceptor.context.page.model.PageInfo;
|
|
||||||
import com.ruoyi.mybatisinterceptor.sql.MybatisPreHandler;
|
|
||||||
import org.apache.ibatis.cache.CacheKey;
|
import org.apache.ibatis.cache.CacheKey;
|
||||||
import org.apache.ibatis.executor.Executor;
|
import org.apache.ibatis.executor.Executor;
|
||||||
import org.apache.ibatis.mapping.BoundSql;
|
import org.apache.ibatis.mapping.BoundSql;
|
||||||
@ -20,7 +16,13 @@ import org.apache.ibatis.session.ResultHandler;
|
|||||||
import org.apache.ibatis.session.RowBounds;
|
import org.apache.ibatis.session.RowBounds;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
import com.ruoyi.common.utils.sql.SqlUtil;
|
import com.ruoyi.common.utils.sql.SqlUtil;
|
||||||
|
import com.ruoyi.mybatisinterceptor.annotation.MybatisHandlerOrder;
|
||||||
|
import com.ruoyi.mybatisinterceptor.context.page.PageContextHolder;
|
||||||
|
import com.ruoyi.mybatisinterceptor.context.page.model.PageInfo;
|
||||||
|
import com.ruoyi.mybatisinterceptor.sql.MybatisPreHandler;
|
||||||
|
|
||||||
import net.sf.jsqlparser.schema.Column;
|
import net.sf.jsqlparser.schema.Column;
|
||||||
import net.sf.jsqlparser.statement.Statement;
|
import net.sf.jsqlparser.statement.Statement;
|
||||||
import net.sf.jsqlparser.statement.select.Limit;
|
import net.sf.jsqlparser.statement.select.Limit;
|
||||||
|
Loading…
Reference in New Issue
Block a user