Spring Aop就是我们常说的面向切面编程,它和IOC构成了spring体系的两大核心,玩明白了这两个,spring就算玩会了。。 spring aop可以干很多事,他就类似于拦截器,能在你的目标方法之前或者之后做一些事儿(类似于方法的增强),例如:权限校验、日志记录、统计等
本文主要讲的是如何利用spring aop实现权限校验和控制
一、首先定义接口(有点spring security那意思了)
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Authority {
}
二、定义切面
我们的权限控制是根据RBAC模型进行的,也就是说一个用户对应多个角色,已经角色对应多种权限,基于这个模型,以下代码就是大体思路
@Slf4j
@Aspect
@Component
public class AnnotationAopTwo {
@Autowired
private HttpServletRequest request;
@Autowired
private RedisUtil redisUtil;
@Autowired
private SysRoleService sysRoleService;
@Pointcut("@annotation(com.qcby.device.manage.annotation.Authority)")
public void viewRecordsPoinCut(){}
@Around("viewRecordsPoinCut()")
public Object Annotation(ProceedingJoinPoint joinPoint) throws Throwable{
log.info("---进入aopAround通知---");
SysUser sysUser = redisUtil.get("SysUser");
List<Long> roleIds = sysUser.getRoleIds();
Set<String> powerStringSet = new HashSet<>();
for (Long roleId : roleIds) {
List<String> powerString = sysRoleService.getPowerString(roleId);
powerStringSet.addAll(powerString);
}
String url = request.getRequestURI();
log.info("===开始进行权限校验===");
if(!powerStringSet.contains(url)){
return ResultJson.error("权限不足");
}
return joinPoint.proceed();
}
}
上面代码提供了大体思路,其实使用aop实现权限校验逻辑还是很清晰的
- 定义接口@Authority
- 定义切面和切点,拦截所有添加了@Authority注解的Controller
- 定义权限验证的逻辑
- 从缓存中获取用户信息
- 获取用户的角色id集合
- 根据角色id利用Set集合保存起来
- 获取请求的路径url
- 判断set集合里面有没有该url,如果有则直接返回,,没有就返回权限不足的信息
文章只提供了大致思路和部分代码,还有很多的优化空间,也可以实现类似spring security的功能,自定义@PreAuthorize和属性hasAuthority等等,里面很多功能还有待挖掘…
|