SpringBoot基础-AOP权限验证
AOP权限验证,@Around使用小案例
·
引言
在我们做项目的时候可能会遇到这样的场景:给用户分配不同的角色,然后不同的角色对某一个方法有不同的权限,有些角色可以访问该方法,有的不能访问。这时候我们可以利用aop实现权限验证。
实现思路就是首先自定义一个注解,在方法上添加该注解,跟据注解的值来判断能否访问该方法。
创建SpringBoot项目
导入依赖
<properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.3.7.RELEASE</spring-boot.version> <commons.io.version>2.5</commons.io.version> <commons.fileupload.version>1.3.3</commons.fileupload.version> <poi.version>4.1.2</poi.version> </properties> <dependencies> <!--aop--> <!--AOP联盟--> <dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version> </dependency> <!--Spring Aspects--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.0.2.RELEASE</version> </dependency> <!--aspectj--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.3</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.12</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- excel工具 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </dependency> <!--io常用工具类 --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>${commons.io.version}</version> </dependency> <!--文件上传工具类 --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>${commons.fileupload.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.72</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.4</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <!-- 日志 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> <exclusions> <!-- 排除spring-boot-starter-logging中的全部依赖 --> <exclusion> <groupId>*</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> <scope>test</scope> <!-- 打包的时候不打spring-boot-starter-logging.jar --> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency> </dependencies>
配置application.yml
mybatis: mapper-locations: classpath:/mybatis/**/*.xml type-aliases-package: com.example.note.domain map-underscore-to-camel-case: true mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl typeAliasesPackage: com.example.note.domain #存放实体类的目录路径 mapperLocations: classpath:mybatis/**/*.xml # 全局配置id自增 => global-config: db-config: id-type: auto server: port: 8088 spring: application: name: note-back datasource: driver-class-name: com.mysql.cj.jdbc.Driver name: defaultDataSource password: '123456789' url: jdbc:mysql://localhost:3306/note?serverTimezone=UTC username: 'root'
数据准备
自定义注解
package com.example.noteback.permission.anno; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; //目标是方法(在方法上添加该注解) @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Permissions { public String value(); }
创建controller类,定义两个方法
package com.example.noteback.permission.controller; import com.example.noteback.permission.anno.Permissions; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("permissions") public class PermissionsController { @Permissions(value = "/permissions/getUser") @GetMapping("/getUser") public String getUser(){ return "User"; } @Permissions(value = "/permissions/getAGi") @GetMapping("/getAGi") public String getAGi(){ return "AGi"; } }
AOP实现权限验证
创建PermissionsValidation类(类名自定义)
import com.example.noteback.permission.anno.Permissions; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; @Aspect @Component public class PermissionsValidation { //切入点 @Pointcut("@annotation(com.example.noteback.permission.anno.Permissions)") public void permissionsPoint() { } @Around("permissionsPoint()") public Object hasPermissions(ProceedingJoinPoint joinPoint) throws Throwable { } }
定义切入点,放到上面的PermissionsValidation类里面
//切入点 /*当我们调用添加 @Permissions 注解的方法时, 下面的方法自动获取被调用的方法*/ @Pointcut("@annotation(com.example.noteback.permission.anno.Permissions)") public void permissionsPoint() { }
使用环绕通知@Around实现权限验证,放到上面的PermissionsValidation类里面
//通过方法名获取切入点 @Around("permissionsPoint()") public Object hasPermissions(ProceedingJoinPoint joinPoint) throws Throwable { //方法签名 MethodSignature methodSignature=(MethodSignature) joinPoint.getSignature(); //获取方法 Method aimMethod= methodSignature.getMethod(); //获取 @Permissions 的值 String permissions=aimMethod.getAnnotation(Permissions.class).value(); //权限集合 List<String> permissionsList=new ArrayList<>(); permissionsList.add("/permissions/getUser"); //返回数据 Object proceed=null; //如果权限集合包含 @Permissions 的值 if(permissionsList.contains(permissions)){ //允许通过,表调用的方法可以往下运行 proceed=joinPoint.proceed(); }else { proceed="没有权限"; } return proceed; }
编写完毕
测试
上面定义的权限集合只包含 "/permissions/getUser"
源码地址
源码地址:git@gitee.com:AGi_R/note.git
在命令框输入:git clone git@gitee.com:AGi_R/note.git 直接下载源码
更多推荐
已为社区贡献5条内容
所有评论(0)