背景
最近在写项目的时候因为前期需求没有说要建立权限系统,用户与角色,角色与权限之间互相绑定,但是到项目中后期,突然提出要分权,这时候如果推到重来的话就很麻烦,如何重新对数据库的表进行设计,相关代码也要重新编写,于是想到使用AOP直接对用户权限进行校验。 笔者是一名大三学生,代码出现问题还请各位指正,笔者不胜感激。
确定切面
首先我们要进行权限验证的接口一定是很多的,如果直接硬编码去实现的话代码的复用性不高且后期难以维护,所以在每次进接口之前先进行权限验证似乎是一个非常好的方式。
编写权限注解
Java
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PermissionAnnotation {
}
注解的作用就是帮助我们确定到底哪一个方法需要进行权限验证。
定义切面
java
@Aspect
@Component
@Order(1)
public class PermissionFirstAdvice {
// 定义一个切面,括号内写入前面自定义注解的路径
@Pointcut("@annotation(com.mu.demo.annotation.PermissionAnnotation)")
private void permissionCheck() {
}
@Around("permissionCheck()")
public Object permissionCheckFirst(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("---进入aopAround通知---");
//因为在登录之后会将用户信息存入缓存当中
//从缓存中获取登录者信息
Optional<SysUser> userOptional = Optional.ofNullable(LoginHelper.getLoginUser());
if(userIdOptional.isPresent()) {
SysUser sysUser = userOptional.get();
//获取角色id
List<Long> roleIds = sysUser.getRoleIds();
Set<String> powerStringSet = new HashSet<>();
for (Long roleId : roleIds) {
//获取角色所对应的权限字符串
//权限字符串和访问路径相同,例如查询权限:user::listPage,删除权限:user::delete等等...
//这里可以优化为直接从缓存当中获取,可以节省很多时间个资源
List<String> powerString = sysRoleService.getPowerString(roleId);
//因为权限字符串可能重复,所以用Set集合保存起来
powerStringSet.addAll(powerString);
}
//获取请求的url
String url = request.getRequestURI();
log.info("===开始进行权限校验===");
if (!powerStringSet.contains(url)) {
return ResultJson.error("权限不足");
}
return joinPoint.proceed();
}else {
return ResultJson.error("用户未登录");
}
}
}
到此以一个简单的权限校验逻辑就写好了。