浅谈基于SpringBoot实现一个简单的权限控制注解
作者:ly931003 发布时间:2022-01-23 16:42:47
注解是 JDK 5.0 引入的一种注释机制。注解可以作用在类型(类、接口、枚举等)、属性、方法、参数等不同位置,具体的 JDK 版本所支持的注解位置可参考 java.lang.annotation.ElementType 。此外还有注解的策略,也就是 RetentionPolicy ,这里不加赘述。
注解可以实现很多功能,其中最主要的就是进行代码标注,所以有时候注解也叫做标注。使用起来也基本顾名思义,就是对代码进行标注,简化部分代码的逻辑。
下面我们就着手实现一个简单的权限控制注解,来对注解有一个基本的了解。
准备
@Permission 注解
注解本身的代码很简单。下面实现的是一个 @Permission 注解,为了方便使用,这里只提供一个属性value,因为如果一个注解中有一个名称为value的属性,且你只想设置value属性(即其他属性都采用默认值或者你只有一个value属性),那么可以省略掉“value=”部分。
import java.lang.annotation.*;
@Target({ElementType.PARAMETER}) // 注解可用于参数
@Retention(RetentionPolicy.RUNTIME) // 注解在运行时可由JVM读入
@Documented
public @interface Permission {
String value() default "";
}
User 类
一个简单的User类,包含 permissions 用于保存用户的权限。
import lombok.Data;
@Data
public class User {
private String id;
private String name;
private Set<String> permissions;
}
UserService 类
简单的 Service 类,用于判断权限。
@Service
public class UserService {
public boolean checkCreatePermission(@Permission("创建用户") User user) {
return true;
}
public boolean checkDeletePermission(@Permission("删除用户") User user) {
return true;
}
}
PermissionAspect 类
利用 SpringBoot 简单地设置切面,获取注解并使用。这里直接
@Aspect
@Component
public class PermissionAspect {
// 需要修改为实际的 Service 所在的 Package
@Pointcut("execution(public * tk.yubarimelon.MongoDemo.service.*.*(..))")
public void permissionCheck() {
}
@Around("permissionCheck()")
public Object before(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] params = joinPoint.getArgs();
// 获取方法,此处可将signature强转为MethodSignature
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
// 获取参数注解,1维是参数,2维是注解
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
for (int i = 0; i < parameterAnnotations.length; i++) {
Object param = params[i];
Annotation[] annotations = parameterAnnotations[i];
if (!(param instanceof User) || annotations.length == 0) {
continue;
}
for (Annotation annotation : annotations) {
if (annotation.annotationType().equals(Permission.class)) {
Permission permission = (Permission) annotation;
User user = (User) param;
if (CollectionUtils.isEmpty(user.getPermissions())) {
log.error(user.getName() + " 无任何权限!");
return false;
}
if (!StringUtils.hasLength(permission.value())) {
log.error(joinPoint.getSignature().toString() + "权限设置异常");
return false;
}
if (!user.getPermissions().contains(permission.value())) {
log.error(joinPoint.getSignature().toString() +": "+user.getName() + " 无权限: " + permission.value());
return false;
}
return joinPoint.proceed();
}
}
}
return joinPoint.proceed();
}
}
ApplicationTests 类
简单的测试类,用于测试代码。这里简单的配置一个用户只有创建用户的权限
@SpringBootTest
class ApplicationTests {
@Autowired
UserService userService;
@Test
void contextLoads() {
}
@Test
void checkUser() {
User user = new User();
user.setName("小明");
Set<String> permissions = new HashSet<>();
permissions.add("创建用户");
user.setPermissions(permissions);
System.out.println("checkCreatePermission " + userService.checkCreatePermission(user));
System.out.println("checkDeletePermission " + userService.checkDeletePermission(user));
}
}
输出如下日志,证明权限设置起作用了。
checkCreatePermission true
2021-01-31 11:44:45.895 ERROR 12388 --- [ main] t.y.MongoDemo.aop.PermissionAspect : boolean tk.yubarimelon.MongoDemo.service.UserService.checkDeletePermission(User): 小明 无权限: 删除用户
checkDeletePermission false
来源:https://segmentfault.com/a/1190000039134345


猜你喜欢
- TCP与UDP都属于TCP/IP协议TCP(Transmission Control Protocol,传输控制协议)是面向连接的协议,也就
- 该着色方法一句着色图层中要素类的某个数值字段的属性值,按这个属性值为每种不同值得要素单独分配一种显示符号样式。关键在于获取该字段所有要素的唯
- 实例如下:func exitApplication() { let app = UIApplication.sh
- 安装完jdk环境后,编写第一个java程序hello.java:public class hello{
- Android 滑动监听的实例详解摘要: ScollBy,ScollTo是对内容的移动,view.ScollyBy是对view的内容的移动&
- 本文实例讲述了Java实现的并发任务处理方法。分享给大家供大家参考,具体如下:public void init() { super.init
- springBoot yml文件的list读取问题折腾了很久,记录下。配置如下# 自定义数据上报信息xx: # 机组信息 &nb
- 一、概述RocketMQ主要提供了两种消费模式:集群消费以及广播消费。我们只需要在定义消费者的时候通过setMessageModel(Mes
- 前言需求使用freemarker生成的静态文件,统一存储在某个服务器上。本来一开始打算使用ftp实现的,奈何老连接不上,改用jsch。毕竟有
- 背景公司开发框架增加了web系统license授权证书校验模块,实行一台机器一个授权证书,初步方案是增加 * 针对全局请求进行拦截校验,评估
- java解决动态配置字段需求是否在开发中遇到有像下图一样管理员配置多个字段让用户填写的需求我的实现方式是通过数据库存储动态json的显示实现
- 因为我本人很喜欢在不同的页面之间跳转时加点好玩的动画,今天无意间看到一个动画效果感觉不错,几种效果图如下:既然好玩就写在博客中,直接说就是:
- 今天来分析Configuration初始化的最后一部分mapper的加载。加载方法mapperElementXMLConfigBuilder
- Android Studio 在引用外部依赖时,发现一直无法引用外部依赖。刚开始以为是墙的问题,尝试修改Gradle配置,未解决问题。最终发
- Spring的HandlerMapping支持 * , * 必须实现HandlerInterceptor接口,此接口里面有下面3中方法:1.
- 多文件上传就是改良一个方法把MultipartFile类换成CommonsMultipartFile类,因为上传多个文件用数组方式的话Mul
- 前言这篇博客学习下Mybatis操作中使用Redis做缓存。这里其实主要学习几个注解:@CachePut、@Cacheable、@Cache
- 在Android程序开发中我们经常遇到四种数据存储方式,每种存储方式都各有不同;以下我分别列举了Android开发中的不同存储方式的特点一,
- ListBox控件的使用: 1)控件属性 Items SelectedItems SelectioModes 2)数据绑定 DataSour
- 前言:Java 中 hashCode() 和 equals() 的关系是面试中的常考点,如果没有深入思考过两者设计的初衷,这个问题将很难回答