0


7.6 SpringBoot AOP实战 统一角色权限校验

CSDN成就一亿技术人

文章目录


前言

通过上文7.5 SpringBoot 拦截器Interceptor实战 统一角色权限校验,很多朋友学会了Interceptor实现以后,很想学习如何使用AOP实现 统一角色权限校验,所以本文就来安排AOP的实现!

对于SpringBoot的AOP的相关基础知识,请参考我之前写过的博客,也是上过综合热榜第一的文章,本文的实战会用到其中的@annotation、@Before、@Around等方式!

非常详细的SpringBoot AOP入门文章!应用范围非常广,可以说是项目必用!学会了快速在项目中使用吧,包括对@Aspect、@Pointcut、@Before、@After、@Around等的说明,以及简单实战案例!
【Spring AOP】@Aspect结合案例详解(一): @Pointcut使用@annotation + 五种通知Advice注解(已附源码)


一、引入AOP starter

在tg-book-common中引入依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>

对于spring boot的starter,我在之前的文章中已经反复说明过多次,不做赘述!
本项目中已经使用中的starter如下:

  • spring-boot-starter-web
  • spring-boot-starter-logging
  • mybatis-spring-boot-starter
  • pagehelper-spring-boot-starter

二、创建切面@Aspect + 定义切点@Pointcut

@Aspect

注解方式,它的概念像@Aspect、@Pointcut、@Before、@After、@Around等注解都是来自于 AspectJ,但是功能的实现是纯 Spring AOP 自己实现的,主要有

两大核心

  • 定义[切入点]:使用 @Pointcut 切点表达式,你可以理解成类似于正则表达式的强大东东。(例如本文的@annotation方式)
  • 定义[切入时机] 和 [增强处理逻辑]五种通知Advice注解 对[切入点]执行增强处理, 包括:@Before、@After、@AfterRunning、@AfterThrowing、@Around

以下使用@Aspect 定义一个切面类,使用@Pointcut定义一个切点,切点表达式使用@annotation方式,也就是注解的方式。

// @Aspect和@Component定义一个切面类,@Slf4j是之前讲过的日志注解@Component@Aspect@Slf4jpublicclassRoleAspect{// 核心一:定义切点(使用@annotation方式)@Pointcut(value ="@annotation( org.tg.book.common.annotation.Role)")publicvoidpointCut(){}}

在这里插入图片描述


三、封装校验@Role角色权限的方法

本文的AOP是上文拦截器Interceptor的另一种实现方式,所以请将上文的AuthInterceptor中的如下代码注释:
在这里插入图片描述
然后把这段代码拿过来,封装成一个方法,放到

RoleAspect

中如下:

/**
 * 将@Role与登录用户的角色对比,如果是管理员返回true
 **/privatebooleancheckAdminRole(Role role){// 校验角色if(role !=null){// 走到这,说明方法上加了@Roleboolean isAdmin =false;AuthContextInfo authInfo =AuthContextInfo.getAuthInfo();for(int roleId : role.roleIds()){if(authInfo.getRoleId().equals(roleId)){
                isAdmin =true;break;}}if(!isAdmin){
            log.info("[403]无权限, authInfo={}", authInfo);returnfalse;}}returntrue;}

方法逻辑很简单:将@Role与登录用户的角色对比,如果是管理员返回true,否则返回false


四、AOP两种实现方式

4.1 前置通知@Before方式

因为角色权限校验代码,发生于【业务方法代码】之前,所以可以使用前置通知@Before方式,代码如下:

@Before("pointCut()")publicvoidbefore(JoinPoint joinPoint)throwsNoSuchMethodException{MethodSignature signature =(MethodSignature) joinPoint.getSignature();Class<?> clazz = joinPoint.getTarget().getClass();Method method = clazz.getMethod(signature.getName(), signature.getParameterTypes());Role role = method.getAnnotation(Role.class);boolean isAdminRole =checkAdminRole(role);if(!isAdminRole){thrownewRuntimeException("无权限");}}

核心逻辑是获得@Role注解,然后进行校验,如果非管理员,则

抛出异常

。这里实现的比较简单,当后面我们实现了【全局异常处理】以后,这里就可以换成自定义的异常类,交给【全局异常处理】统一处理!

4.2 环绕通知@Around方式

如果不抛出异常的话,如何处理?

可以使用@Around方式,环绕通知@Around可以控制在【业务方法代码】之前校验,并且

可以返回结果

,所以我们就不需要抛出异常了!

@Around("pointCut()")publicObjectaround(ProceedingJoinPoint joinPoint)throwsThrowable{MethodSignature signature =(MethodSignature) joinPoint.getSignature();Class<?> clazz = joinPoint.getTarget().getClass();Method method = clazz.getMethod(signature.getName(), signature.getParameterTypes());Role role = method.getAnnotation(Role.class);boolean isAdminRole =checkAdminRole(role);if(!isAdminRole){returnTgResult.fail("403","无权限");}return joinPoint.proceed();}

获取Role 之前的代码都是一模一样的,区别就是这里没有抛出异常,而是返回统一结果TgResult,这也正是

封装统一返回结果的好处之一!!!
特别注意:

before和around是两种实现方式,所以不必在意从joinPoint得到role的重复代码,因为最终只会写一份代码,对于before和around我更

建议使用around的方式!

最后

想要看更多实战好文章,还是给大家推荐我的实战专栏–>《基于SpringBoot+SpringCloud+Vue前后端分离项目实战》,由我和 前端狗哥 合力打造的一款专栏,可以让你从0到1快速拥有企业级规范的项目实战经验!

具体的优势、规划、技术选型都可以在《开篇》试读!

订阅专栏后可以添加我的微信,我会为每一位用户进行针对性指导!

另外,别忘了关注我:天罡gg ,发布新文不容易错过: https://blog.csdn.net/scm_2008

标签: spring boot java 后端

本文转载自: https://blog.csdn.net/scm_2008/article/details/131840651
版权归原作者 天罡gg 所有, 如有侵权,请联系我们删除。

“7.6 SpringBoot AOP实战 统一角色权限校验”的评论:

还没有评论