闲来无事,做了一个自定义注解加AOP切面实现登录角色的权限验证
1、场景
后台表设计为:用户有关联角色,角色关联了该角色所拥有的菜单、以及接口权限。用户登录时按照角色返回该用户可访问的菜单。用户登录后访问某个接口时、需要验证该用户是否有访问该接口的权限,为了实现此想法,我使用了自定义注解加aop切面技术。
2、内容
数据库表
自定义注解类
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Permission {
String value() default "";
String desc() default "";
}
aop类:使用@Before("@annotation(permission)")使得方法在执行Controller接口之前被执行,permissionManager.checkPermission(loginId, permissionId);方法是自己实现的权限校验业务逻辑,这里可根据自己的业务实现。
@Aspect
@Component
public class PermissionAop {
Logger logger = LoggerFactory.getLogger(PermissionAop.class);
@Resource
private PermissionManager permissionManager;
@Pointcut("@annotation(com.ht.route.admin.annotation.Permission)")
private void getPermissionAopPointcut(){}
@Before("@annotation(permission)")
public void doPermissionBefore(Permission permission) throws AppException {
String permissionId = permission.value();
//获取请求头信息
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String loginId = request.getHeader("loginId");//可换为token使用
if (StringUtils.isBlank(loginId)) {
logger.error("PermissionAop.doPermissionBefore =>> 权限验证失败,token信息为空,用户未登录,loginId=null");
throw new AppException(AppErrorCodeEnum.NOT_PERMISSION);
}
Boolean flag = permissionManager.checkPermission(loginId, permissionId);
if (!flag) {
throw new AppException(AppErrorCodeEnum.NOT_PERMISSION);
}
}
@After("@annotation(permission)")
public void afterExecute(JoinPoint joinPoint, Permission permission) {
logger.info("方法执行之后执行");
}
}
在Controller层的应用:在想要执行权限验证的类上加@Permission注解,并将访问该接口的权限标识作为参数传入
public class SysRoleController {
@Resource
private SysRoleService sysRoleService;
@Permission(value = "system:insert:role", desc = "新增角色")
@PostMapping("/auth/addRole")
public DataResult<Boolean> addRole(@LoginSystem LoginBO loginBO, @RequestBody SysRoleBO sysRoleBO) throws AppException {
Boolean data = sysRoleService.addRole(loginBO, sysRoleBO);
return new DataResult<>(data);
}
}
到此便实现了加注解的接口会走权限校验,不加的则不会。