真实SpringBoot项目中基于AOP实现简单的权限管理
首先在pom.xml文件中添加新的依赖
<!-- Spring AOP的实现依托于Aspect框架
所以要引用1.8.5有问题
-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
然后创建枚举类
public enum PermissionEnum {
/* 是否拥有超级管理员权限 */
SUPER_ADMIN("superAdmin"),
/* 是否拥有管理员权限 */
ADMINISTRATOR("Administrator"),
;
private String permission;
PermissionEnum(String permission) {
this.permission = permission;
}
public String getPermission() {
return permission;
}
}
接下来是注解类
/**
* 权限控制注解
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface Permission {
PermissionEnum value();
String msg() default "";
}
在有需要权限校验的切面下添加如下注解
我选择的是在Controller层的接口下添加的
//校验超级管理员权限
@Permission(PermissionEnum.SUPER_ADMIN)
@GetMapping("testBySuperAdmin")
public Result testBySuperAdmin(){
return Result.makeRsp(200,"超级管理员权限控制测试接口");
}
//校验管理员权限
@Permission(PermissionEnum.ADMINISTRATOR)
@GetMapping("testByAdmin")
public Result testByAdmin(){
return Result.makeRsp(200,"管理员权限控制测试接口");
}
接下来定义切面
package com.test.common.pointcut;
import com.test.common.Result;
import com.test.common.annotation.Permission;
import com.test.common.enums.PermissionEnum;
import com.test.common.exception.ServiceException;
import com.test.pojo.entity.TokenEntity;
import com.test.utils.web.token.TokenThreadLocal;
import org.apache.catalina.connector.Response;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 权限认证切面控制
* @Author zjh
* @Date 2019-11-23 17:19
*/
@Aspect
@Component
@ResponseBody
public class AuthorityManagement {
private final Logger logger = LoggerFactory.getLogger(AuthorityManagement.class);
/** 返回的Result对象(封装好的返回给前端的对象) */
/** 在环绕通知中验证权限 */
@Around(value = "@annotation(permission)")
public Result PermissionCheck(ProceedingJoinPoint proceedingJoinPoint
, Permission permission){
//获取当前登录对象的权限标识符(这个地方是因为我已经在拦截器中获取了当前进行此操作的用户的token)
TokenEntity tokenEntity = TokenThreadLocal.get();
//根据我之前定义过的token中,accessLevel值的定义(0:超级管理员、1:管理员、2:一般用户)
Integer accessLevel = tokenEntity.getAccessLevel();
//获取注解的value,判断当前接口是管理员权限还是超级管理员权限
PermissionEnum value = permission.value();
try {
//判断当前接口要验证的权限是否为超级管理员
if(value.equals(PermissionEnum.SUPER_ADMIN)){
if(accessLevel == 0){
//当前登录用户为超级管理员
Object proceed = proceedingJoinPoint.proceed();
return (Result)proceed;
}else {
logger.error("权限认证: " + tokenEntity.toString() + "不是超级管理员没有权限执行此操作");
return Result.makeRsp(500,"没有权限执行此操作");
}
}else if(value.equals(PermissionEnum.ADMINISTRATOR)){
//否则判断当前接口要验证的权限是否为管理员
if(accessLevel == 1 || accessLevel == 0){
//当前登录用户为管理员
Object proceed = proceedingJoinPoint.proceed();
return (Result)proceed;
}else {
/* 日志记录 */
logger.error("权限认证: " + tokenEntity.toString() + "不是管理员没有权限执行此操作");
return Result.makeRsp(500,"没有权限执行此操作");
}
}
}catch (Throwable throwable) {
/* 日志记录 */
/* 捕获方法执行中的异常,抛出 */
logger.error("PermissionCheckThrowable" + throwable.getMessage());
/* 当前没有权限 */
return Result.makeRsp(500,throwable.getMessage());
}
return Result.makeRsp(500,"没有权限执行此操作");
}
}
以上均是项目中实际代码,建议朋友们参考使用,不要照搬;若有什么不明白的地方,可以留言,有空我会回答的~