聊聊权限管理

matevip 2021-5-31 大约 3 分钟

# 一、后台权限控制之方法级控制

# 1.1 引入依赖

<dependency>
    <groupId>vip.mate</groupId>
    <artifactId>mate-starter-web</artifactId>
</dependency>
1
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>
1
2
3
4
5
6
7
8
9
10
11
12

其中

<dependency>
    <groupId>vip.mate</groupId>
    <artifactId>mate-starter-auth</artifactId>
</dependency>
1
2
3
4

这个认证模块实现了方法级的认证功能,可以继续往下看,下面会继续讲解其功能及实现。

题外话:mate-starter-web引用了数据库、redis和认证模块。也就是说一旦引用了这个模块,数据库和redis是必备的,如果只想做一个前置模块,不连数据库和redis,就需要排除掉相关依赖。

# 1.2 使用方法

在controller的控制器类的方法,增加这么一段

@PreAuth(hasPerm = "sys:log:delete")
1

其中hasPerm如果不加,就直接验证token,如果添加了,则验证这个用户是否有sys:log:delete这个权限。

所以只验证token的写法是

@PreAuth
1

# @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);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 为什么不用security里自带的权限控制功能呢?

有人就好奇,也啥要自己弄一套,不用spring-cloud-starter-oauth2中自带的方法呢?这样不是多此一举么? 这样设计的原因就是为了方便,如果引入了mate-starter-security这个模块后,会自动将所有的方法都加上权限验证,如果不想验证还得加忽略方法。

而现在的设计是:

  1. 不加注解 none -> 不验证权限;
  2. 只加 @PreAuth -> 粗颗粒度验证;
  3. @PreAuth(hasPerm = "xxx:xxx") -> 细颗粒度验证

# 二、后台权限控制之网关控制

如果方法级控制还不过瘾的话呢,接下来就讲讲网关统一控制下权限,这个controller就不用再加注解了,减少开发工作量,当然了加上工作量也不大,况且代码生成工具也就直接给生成了。😄

# 2.1 全局控制类之PreUaaFilter

因为网关是整个微服务项目的入口,那么如果想统一拦截,就只能走网关了。 完整路径:

src/main/java/vip/mate/gateway/filter/PreUaaFilter.java
1

为了避免与mate-starter-auth的认证冲突,所以增加了一个开关,开关的配置类: mate-starter-cloud模块下:

src/main/java/vip/mate/core/cloud/props/MateApiProperties.java
1

有两个参数:

/**
  * 忽略URL,List列表形式
*/
private List<String> ignoreUrl = new ArrayList<>();

/**
  * 是否启用网关鉴权模式
*/
private Boolean enable = false;
1
2
3
4
5
6
7
8
9
  • enable: 默认关闭状态 如果需要开启,则在配置文件里增加
mate:
  uaa:
    enable: true
1
2
3
  • ignoreUrl: 忽略url 统一认证如果有些地址不加验证,则在此忽略,在配置文件中配置即可。

# 三、两种实现方式的对比

对比项 方法级鉴权 网关鉴权
灵活性 全局拦截,需要配置忽略地址
代码量
颗粒度 粗,只做token鉴权

# 四、基于security的鉴权方式

需要增加一些专属配置,忽略的模式,类似网关鉴权,后续会专门写文档介绍。

上次编辑于: 2021年6月6日 17:30
贡献者: matevip