聊聊权限管理
# 一、后台权限控制之方法级控制
# 1.1 引入依赖
<dependency>
<groupId>vip.mate</groupId>
<artifactId>mate-starter-web</artifactId>
</dependency>
2
3
4
打开mate-starter-web,其依赖了以下这些包
<dependency>
<groupId>vip.mate</groupId>
<artifactId>mate-starter-database</artifactId>
</dependency>
<dependency>
<groupId>vip.mate</groupId>
<artifactId>mate-starter-redis</artifactId>
</dependency>
<dependency>
<groupId>vip.mate</groupId>
<artifactId>mate-starter-auth</artifactId>
</dependency>
2
3
4
5
6
7
8
9
10
11
12
其中
<dependency>
<groupId>vip.mate</groupId>
<artifactId>mate-starter-auth</artifactId>
</dependency>
2
3
4
这个认证模块实现了方法级的认证功能,可以继续往下看,下面会继续讲解其功能及实现。
题外话:mate-starter-web引用了数据库、redis和认证模块。也就是说一旦引用了这个模块,数据库和redis是必备的,如果只想做一个前置模块,不连数据库和redis,就需要排除掉相关依赖。
# 1.2 使用方法
在controller的控制器类的方法,增加这么一段
@PreAuth(hasPerm = "sys:log:delete")
其中hasPerm如果不加,就直接验证token,如果添加了,则验证这个用户是否有sys:log:delete这个权限。
所以只验证token的写法是
@PreAuth
# @PreAuth这个注解,怎么实现权限拦截的呢?
依次打开:mate-starter-auth > src/main/java/vip/mate/core/auth/aspect/PreAuthAspect.java 这个类,这个类是一个拦截器。权限拦截都在这里了。
核心代码摘要如下:
@Around("@annotation(vip.mate.core.auth.annotation.PreAuth)")
public Object around(ProceedingJoinPoint point) throws Throwable {
Signature signature = point.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
PreAuth preAuth = method.getAnnotation(PreAuth.class);
if (ObjectUtils.isEmpty(preAuth)) {
return point.proceed();
}
if (hasPerm(preAuth.hasPerm())) {
return point.proceed();
} else {
throw new TokenException(MateExceptionEnum.PRE_AUTH_NOT_PRIVILEGE);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 为什么不用security里自带的权限控制功能呢?
有人就好奇,也啥要自己弄一套,不用spring-cloud-starter-oauth2中自带的方法呢?这样不是多此一举么? 这样设计的原因就是为了方便,如果引入了mate-starter-security这个模块后,会自动将所有的方法都加上权限验证,如果不想验证还得加忽略方法。
而现在的设计是:
- 不加注解
none
-> 不验证权限; - 只加
@PreAuth
-> 粗颗粒度验证; - 加
@PreAuth(hasPerm = "xxx:xxx")
-> 细颗粒度验证
# 二、后台权限控制之网关控制
如果方法级控制还不过瘾的话呢,接下来就讲讲网关统一控制下权限,这个controller就不用再加注解了,减少开发工作量,当然了加上工作量也不大,况且代码生成工具也就直接给生成了。😄
# 2.1 全局控制类之PreUaaFilter
因为网关是整个微服务项目的入口,那么如果想统一拦截,就只能走网关了。 完整路径:
src/main/java/vip/mate/gateway/filter/PreUaaFilter.java
为了避免与mate-starter-auth的认证冲突,所以增加了一个开关,开关的配置类: mate-starter-cloud模块下:
src/main/java/vip/mate/core/cloud/props/MateApiProperties.java
有两个参数:
/**
* 忽略URL,List列表形式
*/
private List<String> ignoreUrl = new ArrayList<>();
/**
* 是否启用网关鉴权模式
*/
private Boolean enable = false;
2
3
4
5
6
7
8
9
- enable: 默认关闭状态 如果需要开启,则在配置文件里增加
mate:
uaa:
enable: true
2
3
- ignoreUrl: 忽略url 统一认证如果有些地址不加验证,则在此忽略,在配置文件中配置即可。
# 三、两种实现方式的对比
对比项 | 方法级鉴权 | 网关鉴权 |
---|---|---|
灵活性 | 强 | 全局拦截,需要配置忽略地址 |
代码量 | 小 | 无 |
颗粒度 | 细 | 粗,只做token鉴权 |
# 四、基于security的鉴权方式
需要增加一些专属配置,忽略的模式,类似网关鉴权,后续会专门写文档介绍。