代码如下:
写一个切面
必须要有
@Slf4j 日志输出(添加了该注释之后,就可以在代码中直接饮用log.info( ) 打印日志了)
@Aspect 声明是一个切面
@Component(支持bean注入)
注释
package io.agilefast.aspect;
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import io.agilefast.sen.SensitiveFilter;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.operators.relational.Matches;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.http.server.PathContainer;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.util.pattern.PathPattern;
import org.springframework.web.util.pattern.PathPatternParser;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;
/**
* @author yuelian
* @version V1.0.0
* @program EPS_Api
* @description
* @create 2022-08-28 19:13
**/
@Slf4j
@Aspect
@Component
public class SensitiveAspect {
private static final Log Logger = LogFactory.getLog(io.agilefast.aspect.SensitiveAspect.class);
//白名单
private static final String[] witheUrlList = new String[]{
"/api/system/sensitive/**",
"/api/login/**",
"/api/donateInfo/imgUrl/**"
};
@Resource
SensitiveFilter sensitiveFilter;
// 拦截controller所有方法
//@Pointcut("execution(public * com.ruijie.ops.forum.controller..*.*(..))")
// 只拦截post和put请求
@Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping)||@annotation(org.springframework.web.bind.annotation.PutMapping)")
public void params() {
}
@Around("params()")
public Object around(ProceedingJoinPoint point) throws Throwable {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
//请求路径
String requestURI = request.getRequestURI();
//是否在白名单内
boolean existWhiteList = isExistWhiteList(requestURI);
//获取请求参数以及类型
Object[] args = point.getArgs();
if (existWhiteList){
//白名单内直接放行
return point.proceed(args);
}
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
Class<?>[] paramTypes = method.getParameterTypes();
// 遍历args
for (int i = 0; i < args.length; i++) {
Object value = args[i];
Logger.info("输入参数为-[" + args[i] + "]");
//String类型参数直接过滤
if (paramTypes[i].isAssignableFrom(String.class)) {
if (null != value) {
value = args[i];
value = sensitiveFilter.filter((String) value);
}
} else { //对象类型遍历参数,对String类型过滤
Field[] fields = value.getClass().getDeclaredFields(); // 通过反射获取对象
for (Field field : fields) {
Class<?> type = field.getType();
if(type.isAssignableFrom(String.class)){ // 如果是String则过滤
field.setAccessible(true);
String fieldValue = (String)field.get(value);
if(null != fieldValue){
fieldValue = sensitiveFilter.filter(fieldValue);;
field.set(value,fieldValue);
}
}
}
}
args[i] = value;
}
//if(result.length()>=1){
// //自定义的异常
// Logger.info("敏感词是-" + result);
// //throw new BizException("500","您输入的内容有敏感词");
//}
Logger.info("当前调用接口-[" + request.getRequestURL() + "]");
return point.proceed(args);
}
//@AfterReturning(returning = "ret", pointcut = "params()")
//public void doAfterReturning(Object ret) {
//}
private boolean match(String pathPattern, String path) {
return new PathPatternParser().parse(pathPattern).matches(PathContainer.parsePath(path));
}
private boolean isExistWhiteList(String path){
for (int i = 0; i < witheUrlList.length; i++) {
String s = witheUrlList[i];
boolean match = match(s, path);
if (match){
return true;
}
}
return false;
}
}