分享!! 如何自定义权限校验的注解并用AOP拦截实现权限校验
Customize permission verification annotation and implement it with AOP
详细步骤
创建自定义注解
自定义如下
解释一下:
@Target(ElementType.METHOD) // 指定为method上使用的注解
@Retention(RetentionPolicy.RUNTIME) // 在运行时保留
String mustRole() default "" // 注解需要提供一个String类型的参数,不提供的话默认是空字符串
接下来使用AOP来拦截写了这个注解的全部方法
先创建拦截器
具体代码如下
代码已经逐行写了注释进行解释了,所以直接看注释就行了
@Aspect
@Component
public class AuthInterceptor {
@Resource
private UserService userService; // 后续会使用到,所以注入一下UserService
@Around("@annotation(authCheck)") // 定义一个环绕通知,根据参数AuthCheck authCheck推断出需要拦截所有带有AuthCheck注解的方法
public Object doInterceptor(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable {
String mustRole = authCheck.mustRole(); //拿到被拦截的方法上面的注解中传入的参数
// 获取与当前线程关联的RequestAttributes对象
RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); // 转化为HttpServletRequest,拿到当前请求对象
// 拿到当前登录用户
User loginUser = userService.getLoginUser(request);
// 查询一下这个被拦截的注解里面传进来的参数是不是下面我们自己定义的三种之一
//USER("用户", "user"),
//ADMIN("管理员", "admin"),
// BAN("被封号", "ban");
UserRoleEnum mustRoleEnum = UserRoleEnum.getEnumByValue(mustRole);
// 传进来的参数不是这三种,那就认为不需要什么权限了,直接放行就行了
if (mustRoleEnum == null) {
return joinPoint.proceed();
}
// 下面是指定了需要权限的情况
// 先拿到当前登录用户的角色,也就是权限类型
UserRoleEnum userRoleEnum = UserRoleEnum.getEnumByValue(loginUser.getUserRole());
// 如果当前登录用户啥权限都没,直接抛异常
if (userRoleEnum == null) {
throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
}
// 当前登录用户要是被封号了,直接抛异常
if (UserRoleEnum.BAN.equals(userRoleEnum)) {
throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
}
// 下面就是 当前登录有权限,而且不是被封号这种
if (UserRoleEnum.ADMIN.equals(mustRoleEnum)) {
// 假设定义了管理员权限,来判断一下用户是不是管理院权限
if (!UserRoleEnum.ADMIN.equals(userRoleEnum)) {
// 如果用户不是管理员权限,抛异常
throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
}
}
// 到这里说明 通过权限校验了
// 1. 需要管理员权限,当前登录用户就是
// 2. 不需要管理员权限,当前用户是用户权限或者是管理员权限
return joinPoint.proceed();
}
}