EL-ADMIN的权限管理

  • Post author:
  • Post category:其他


参考官方文档:

权限管理


https://el-admin.vip/guide/hdsc.html



一、官方文档介绍

本系统权限控制采用

RBAC

思想。简单地说,一个用户拥有若干角色,每一个角色拥有若干个菜单,菜单中存在菜单权限与按钮权限, 这样,就构造成“用户-角色-菜单” 的授权模型。在这种模型中,用户与角色、角色与菜单之间构成了多对多的关系,如下图

在这里插入图片描述



权限控制

本系统安全框架使用的是 Spring Security + Jwt Token, 访问后端接口需在请求头中携带token进行访问,请求头格式如下:

# Authorization: Bearer 登录时返回的token
Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTU1ODk2NzY0OSwiaWF0IjoxNTU4OTQ2MDQ5f



数据交互

用户登录 -> 后端验证登录返回 token -> 前端带上token请求后端数据 -> 后端返回数据, 数据交互流程如下:

在这里插入图片描述



权限注解


Spring Security

提供了

Spring EL

表达式,允许我们在定义接口访问的方法上面添加注解,来控制访问权限,常用的

EL

如下

表达式 描述
hasRole([role]) 当前用户是否拥有指定角色。
hasAnyRole([role1,role2]) 多个角色是一个以逗号进行分隔的字符串。如果当前用户拥有指定角色中的任意一个则返回true。

下面的接口表示用户拥有

admin



menu:edit

权限中的任意一个就能能访问

update

方法, 如果方法不加

@preAuthorize

注解,意味着所有用户都需要带上有效的

token

后能访问

update

方法

@Log(description = "修改菜单")
@PutMapping(value = "/menus")
@PreAuthorize("hasAnyRole('admin','menu:edit')")
public ResponseEntity update(@Validated @RequestBody Menu resources){
    // 略
}

由于每个接口都需要给超级管理员放行,而使用

hasAnyRole('admin','user:list')

每次都需要重复的添加 admin 权限,因此在新版本 (2.3) 中加入了自定义权限验证方式,在验证的时候默认给拥有admin权限的用户放行。


源码:

// eladmin-common -> me.zhengjie.config.ElPermissionConfig
@Service(value = "el")
public class ElPermissionConfig {

    public Boolean check(String ...permissions){
        // 获取当前用户的所有权限
        List<String> elPermissions = SecurityUtils.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
        // 判断当前用户的所有权限是否包含接口上定义的权限
        return elPermissions.contains("admin") || Arrays.stream(permissions).anyMatch(elPermissions::contains);
    }
}


使用方式:

@PreAuthorize("@el.check('user:list','user:add')") 



接口放行

在我们使用的时候,有些接口是不需要验证权限的,这个时候就需要我们给接口放行,使用方式如下


1、使用注解方式

只需要在Controller的方法上加入该注解即可

@AnonymousAccess


2、修改配置文件方式


eladmin-system -> modules -> security -> config -> SecurityConfig

TIP

使用

permitAll()

方法所有人都能访问,包括带上

token

访问

使用

anonymous()

所有人都能访问,但是带上

token

访问后会报错

// 关键代码,部分略
protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity
            // 支付宝回调
            .antMatchers("/api/aliPay/return").anonymous()
            // 所有请求都需要认证
            .anyRequest().authenticated();
    httpSecurity
            .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
}



二、RBAC



RBAC是什么?

RBAC 是基于角色的访问控制(Role-Based Access Control )在 RBAC 中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便。

在这里插入图片描述



Demo


用户表

用户id 用户名 性别
1 张三
2 李四
3 王五


用户-角色表

id 用户id 角色id
1 1 {1,2,3}
2 2 {2}
3 3 {3}


角色表

角色id 角色名称
角色表

角色level
角色描述
1 admin 1 管理员
2 staff 2 职工
3 visitor 3 游客


权限表

权限id 权限内容
1 admin
2 user:del
3 user:add
4 user:edit


角色-授权表

id 角色id 权限id
1 1 {1,2,3}
2 2 {2,4}
3 3 {3}

这个是标准的RBAC的权限设置思路,接口的安全由权限表直接控制,之后将权限赋予对应的角色,这样用户有什么角色就有什么接口权限。

怎么使用这种表的设计。

在这里插入图片描述

这三层就是表对应的关系。


代码实现(伪)

@Controller
@RequestMapping("/user")
public UserController{
	
	@PostMapping()
	@PreAuthorize("hasAnyRole('admin')")
	public void createUser(){
		// 拥有admin权限的角色才能使用	
	}
	
	@PutMapping()
	@PreAuthorize("hasAnyRole('admin','user:edit')")
	public void update(){
		// 拥有 admin 或者 user:edit 权限的角色才能使用	
	}
	
	@DeleteMapping()
	@PreAuthorize("hasAnyRole('user:del')")
	public void dataController(){
		// 拥有 user:del 权限的角色才能使用
	}
}

通过上述图,如果用户发出接口请求,

会从根据当前用户的角色寻找此角色的权限接口有哪些,最后自动判断后通过接口

所以不要再写根据当前用户角色判断业务逻辑的方式了。


1、权限赋予:


权限赋予是把当前用户的权限拉出来,然后分配的客服可以小于等于当前用户的权限。


2、权限加载:


正常的加载权限,当用户登录后,并且第一次使用权限判断的时候, Shiro 会去加载权限。


3、权限判断:


走正常用户权限判断,但是数据操作需要判断是不是当前归属的用户的数据,其实这个是属于业务层,就算你不是客服,也是需要判断。


4、禁用|启用:


禁用启用,也是正常的用户流程,添加到禁用列表里,如果被禁用,就无法操作任何内容。



三、eladmin中的权限管理

在这里插入图片描述

el-admin中将权限标识放在了permission字段



所谓的权限控制说白了,就是一个字符串,在前端 用户登录后会查到当前用户的所有权限标识符,进行crud操作的时候会去匹配,匹配到这个字符串,就是有权限,能操作,反之则不能。 在后端 访问接口的时候通过token 查询到当前用户的所有权限去匹配接口上的权限标识,进行判断。

接下来详细看议案源码中是怎么实现的吧



权限注解

前面已经介绍过,在登录后访问接口时会携带token进行识别

随便打开一个接口,

在这里插入图片描述

可以看到标红的注解

@PreAuthorize("@el.check(‘user:add’)")

,这是什么意思呢?在IDEA环境下,按住ctrl键点击@el.check,可以看到源代码如下:

/**
 * @author Zheng Jie
 */
@Service(value = "el")
public class ElPermissionConfig {

    public Boolean check(String ...permissions){
        // 获取当前用户的所有权限
        List<String> elPermissions = SecurityUtils.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
        // 判断当前用户的所有权限是否包含接口上定义的权限
        return elPermissions.contains("admin") || Arrays.stream(permissions).anyMatch(elPermissions::contains);
    }
}

这里的意思就是,用户的权限包含 admin 或 接口上的权限标识符 就返回true



界面如何添加权限

在这里插入图片描述

创建好权限后与角色绑定

在这里插入图片描述

保存后,即可在数据库中看到

在这里插入图片描述



前端对权限的判断

在这里插入图片描述

在这里插入图片描述

用户登录成功后,会查询到当前用户的所有信息(包括权限信息),同时这些信息也会存在token中,在前端操作中,会通过这些信息进行判断,访问后端接口则通过token

这就是

RBAC

的权限设计思想,并没有想象中那么复杂



版权声明:本文为su2231595742原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。