本文介绍了spring boot 通过aop和自定义注解实现权限控制,分享给大家,具体如下:
源码:
思路
pom文件 引入aop
org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-aop
自定义注解 visitpermission
@target(elementtype.method)
@retention(retentionpolicy.runtime)
public @interface visitpermission {
/**
* 用于配置具体接口的权限值
* 在数据库中添加对应的记录
* 用户登录时,将用户所有的权限列表放入redis中
* 用户访问接口时,将对应接口的值和redis中的匹配看是否有访问权限
* 用户退出登录时,清空redis中对应的权限缓存
*/
string value() default "";
}
需要设置权限的接口上加入注解 @visitpermission(value)
@restcontroller
@requestmapping("/permission")
public class permissioncontroller {
/**
* 配置权限注解 @visitpermission("permission-test")
* 只用拥有该权限的用户才能访问,否则提示非法操作
*/
@visitpermission("permission-test")
@getmapping("/test")
public string test() {
system.out.println("================== step 3: doing ==================");
return "success";
}
}
定义权限aop
@aspect
@component
public class permissionaspect {
/**
* 切入点
* 切入点为包路径下的:execution(public * org.ylc.note.aop.controller..*(..)):
* org.ylc.note.aop.controller包下任意类任意返回值的 public 的方法
*
* 切入点为注解的: @annotation(visitpermission)
* 存在 visitpermission 注解的方法
*/
@pointcut("@annotation(org.ylc.note.aop.annotation.visitpermission)")
private void permission() {
}
/**
* 目标方法调用之前执行
*/
@before("permission()")
public void dobefore() {
system.out.println("================== step 2: before ==================");
}
/**
* 目标方法调用之后执行
*/
@after("permission()")
public void doafter() {
system.out.println("================== step 4: after ==================");
}
/**
* 环绕
* 会将目标方法封装起来
* 具体验证业务数据
*/
@around("permission()")
public object doaround(proceedingjoinpoint proceedingjoinpoint) throws throwable {
system.out.println("================== step 1: around ==================");
long starttime = system.currenttimemillis();
/*
* 获取当前http请求中的token
* 解析token :
* 1、token是否存在
* 2、token格式是否正确
* 3、token是否已过期(解析信息或者redis中是否存在)
* */
servletrequestattributes attributes = (servletrequestattributes) requestcontextholder.getrequestattributes();
httpservletrequest request = attributes.getrequest();
string token = request.getheader("token");
if (stringutils.isempty(token)) {
throw new runtimeexception("非法请求,无效token");
}
// 校验token的业务逻辑
// ...
/*
* 获取注解的值,并进行权限验证:
* redis 中是否存在对应的权限
* redis 中没有则从数据库中获取权限
* 数据空中没有,抛异常,非法请求,没有权限
* */
method method = ((methodsignature) proceedingjoinpoint.getsignature()).getmethod();
visitpermission visitpermission = method.getannotation(visitpermission.class);
string value = visitpermission.value();
// 校验权限的业务逻辑
// list