一:先写一个注解:
/** * 用户请求权限校验 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyPermissionTag { //MyPermissionTag就是注解的名字 //下面的value和name两个字段就是这个注解的两个入参,使用注解不写入参就直接默认为"",z这个默认值是自定义的。 String value() default ""; String name() default ""; }
二:就是写一个aop的拦截切面入口和拦截信息处理的代码
package com.example.redislocks.aspect; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.example.redislocks.annottion.MyPermissionTag; import com.example.redislocks.dao.ModuleDao; import com.example.redislocks.dao.RoleDao; import com.example.redislocks.entity.Module; import com.example.redislocks.entity.Role; import com.example.redislocks.entity.Student; import com.example.redislocks.mapper.RoleMapper; import com.example.redislocks.vo.StudentVo; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; import org.apache.ibatis.binding.MapperMethod; 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.Before; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.lang.reflect.Method; import java.sql.Wrapper; import java.util.List; import java.util.Optional; import static com.baomidou.mybatisplus.core.toolkit.Wrappers.query; @Slf4j @Aspect @Component public class AuthInterceptor { @Resource private RoleMapper roleMapper; @Resource private RoleDao roleDao; @Resource private ModuleDao moduleDao; /** * 参数处理 * * @param point */ @Before("@annotation(com.example.redislocks.annottion.MyPermissionTag)") public void beforeProReq(JoinPoint point) { log.info("前置拦截-开始"); StudentVo req = getOperationRequest(point.getArgs()); if (req != null) { //解密帐号 // log.info("前置拦截-开始解密ACCOUNT:{}", req.getAccount()); // log.info("前置拦截-结束解密ACCOUNT:{}", req.getAccount()); } log.info("前置拦截-结束"); } @Around("@annotation(com.example.redislocks.annottion.MyPermissionTag)") public Object authCheck(ProceedingJoinPoint pjp) throws Throwable { log.info("权限拦截-开始"); //请求方法 ReqMethod reqMethod = getPermissionTag(pjp); MyPermissionTag myPermissionTag =reqMethod.perTag; log.info(myPermissionTag.value()); //获取配置的值 log.info("权限拦截-开始-拦截到方法:{}", reqMethod.getMethodName()); if("true".equals(myPermissionTag.value().toString())){ //错误返回 Response notGoRes = new Response(); StudentVo req = getOperationRequest(pjp.getArgs()); if (req!=null) { Role role = roleMapper.selectOne(Wrappers.<Role>query().lambda().eq(Role::getNo, Optional.ofNullable(req.getNo()).orElse("") )); Module module = moduleDao.selectOne(Wrappers.<Module>query().lambda().eq(Module::getName, Optional.ofNullable(reqMethod.getMethodName()).orElse(""))); if (new Integer(role.getRolesize()).intValue() >=new Integer(module.getRolesize()).intValue()){ log.info("完成请求校验:"+req.getName()); }else { log.info("你的权限不够"); return notGoRes; } System.out.println(role.getNo()); } // 校验请求对象 if (req == null) { //notGoRes.setErrorMsg("(AUTH)未能获得有效的请求参数!"); log.info("(AUTH-NO)未能获得有效的请求参数!"); return notGoRes; } // }else if ("龙承贵".equals(req.getName())){ // //可以在这里根据请求参数对请求做进一步校验 // log.info("完成请求校验:"+req.getName()); // }else { // return notGoRes; // } }else { log.info("未开启权限校验"); } return pjp.proceed(); } /** * 获取 request 接口中的请求参数 * @param args * @return */ private StudentVo getOperationRequest(Object[] args) { if (args == null || args.length <= 0) { log.error("AUTH权限验证:拦截方法的请求参数为空!"); return null; } Object obj = args[0]; if (obj instanceof StudentVo) { log.info("AUTH权限验证:请求对象为正确的OperationRequest对象"); return (StudentVo) obj; }else if(args[0] instanceof MapperMethod.ParamMap){ log.info("AUTH权限验证:请求对象为正确的OperationRequest对象"); return (StudentVo) ((MapperMethod.ParamMap<?>) args[0]).values().toArray()[0]; } return null; } /** * 获取拦截的资源标签 * 这里可以获取方法名+注解信息(包括 key+value 等) * @param pjp * @return * @throws SecurityException * @throws NoSuchMethodException */ private ReqMethod getPermissionTag(ProceedingJoinPoint pjp) throws NoSuchMethodException, SecurityException { Signature signature = pjp.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method targetMethod = methodSignature.getMethod(); Method realMethod = pjp.getTarget().getClass().getDeclaredMethod(signature.getName(), targetMethod.getParameterTypes()); MyPermissionTag permissionTag = realMethod.getAnnotation(MyPermissionTag.class); return new ReqMethod(permissionTag, realMethod.getName()); } @Setter @Getter class ReqMethod { private MyPermissionTag perTag; private String methodName; public ReqMethod(MyPermissionTag perTag, String methodName) { this.perTag = perTag; this.methodName = methodName; } } } 三:就直接上例子:使用注解进行请求拦截
@PostMapping("/helloluo") @MyPermissionTag(value = "true") public String helloluo(@RequestBody StudentVo studentVo){ return "Hello World"+studentVo.getName(); }
结果: