1.定义注解 @CheckSign :
代码语言:javascript复制package com.un.framework.aspectj.lang.openapi;
import java.lang.annotation.*;
/**
* 校验签名
*
* @author shiye
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CheckSign {
/**
* 模块
*/
public String title() default "";
}
2.定义基础请求对象,用来需要检验签名的参数基础类
子类需要继承改方法,并且重写你需要校验签名的参数
代码语言:javascript复制tranceToStr()
代码语言:javascript复制package com.un.project.system.domain.other;
import io.swagger.annotations.ApiModelProperty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @author shiye
* @create 2021-08-16 13:45
*/
public class BaseRequestParm implements Serializable {
/**
* appId
*/
@ApiModelProperty(value = "appId")
@NotNull(message = "appId不能为空")
protected String appId;
/**
* 签名
*/
@ApiModelProperty(value = "签名")
@NotNull(message = "sign不能为空")
protected String sign;
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
/**
* 按key的升序排列首尾相接(出了sigin字段)
* 子类方法需要实现改方法
* @return
*/
public String tranceToStr() {
StringBuffer strBuff = new StringBuffer();
strBuff.append("appId");
strBuff.append(appId);
return strBuff.toString();
}
}
3. 定义AOP环绕通知拦截信息
代码语言:javascript复制package com.un.framework.aspectj.lang.openapi;
import com.un.common.utils.security.Md5Utils;
import com.un.project.system.controller.app.BaseResult;
import com.un.project.system.domain.other.BaseRequestParm;
import com.un.project.system.domain.other.CommunityInfoParams;
import com.un.project.system.domain.other.QueryHouseChangeVo;
import com.un.project.system.domain.other.StructAndUserInfoParams;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
/**
* 签名校验处理
*
* @author shiye
*/
@Aspect
@Component
public class CheckSignAspect {
private static final String secret_key = "CRVFSMQA3P2ZKIBU5NOVY9YKH6O1TXPI";
private static final Logger log = LoggerFactory.getLogger(CheckSignAspect.class);
/**
* 配置织入点
*/
@Pointcut("@annotation(com.un.framework.aspectj.lang.openapi.CheckSign)")
public void logPointCut() {
}
/**
* 环绕通知
*
* @param point 切点
*/
@Around("logPointCut()")
public BaseResult doAfterThrowing(ProceedingJoinPoint point) throws Throwable {
Boolean flag = beforHandleSign(point);
log.info("签名校验状态: " flag);
if (flag == true) {
return (BaseResult) point.proceed();
}
return BaseResult.buildFail("签名校验失败");
}
/**
* 前置通知处理
*
* @param joinPoint
*/
protected Boolean beforHandleSign(ProceedingJoinPoint joinPoint) {
try {
/**
* 获得注解
*/
CheckSign checkSign = getAnnotationCheckSign(joinPoint);
if (checkSign == null) {
return false;
}
//获取拦截方法的参数
Object[] params = joinPoint.getArgs();
if (params == null || params.length == 0) {
return false;
}
//获取请求参数
Object obj = params[0];
//根据不同的请求参数进行验签
if (obj instanceof BaseRequestParm) {
BaseRequestParm baseRequestParm = (BaseRequestParm) params[0];
if (baseRequestParm == null) {
return false;
}
String tranceToStr = baseRequestParm.tranceToStr();
String beforSign = secret_key tranceToStr secret_key;
String sign = Md5Utils.hash(beforSign).toUpperCase();
log.info(" ==== 本系统加签值 ==== " sign);
if (sign != null && sign.equals(baseRequestParm.getSign().toUpperCase())) {
return true;
}
}
} catch (Exception exp) {
// 记录本地异常日志
log.error("==前置通知异常==");
log.error("异常信息:{}", exp.getMessage());
exp.printStackTrace();
}
return false;
}
/**
* 是否存在注解,如果存在就获取
*/
private CheckSign getAnnotationCheckSign(JoinPoint joinPoint) throws Exception {
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method != null) {
return method.getAnnotation(CheckSign.class);
}
return null;
}
/**
* 判断是否需要过滤的对象。
*
* @param o 对象信息。
* @return 如果是需要过滤的对象,则返回true;否则返回false。
*/
public boolean isFilterObject(final Object o) {
return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse;
}
}
4.调用方式 (只需要一行代码就可以轻轻松松的进行拦截,想拦截哪就拦截哪) : @CheckSign(title = "****")
代码语言:javascript复制 @PostMapping("/changeData")
@CheckSign(title = "****")
public BaseResult<HouseChangeDto> changeData(@RequestBody @Validated QueryHouseChangeVo queryHouseChangeVo) {
return null;
}