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

安全框架使用的是 Spring Security + Jwt Token,
访问后端接口需在请求头中携带token进行访问,请求头格式如下:
# Authorization: Bearer 登录时返回的token
Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJ1aWQiOiIzMGY5ZWRhNTk3MGM0MGQzYWZlNzFjOTUwMjliM2Q4MCIsInVzZXJJZCI6MSwic3ViIjoiYWRtaW4ifQ.s_PTVM2xMhCKjyHogXs4ZEkTJx6PvaBooAgVkAlnaF8V40AnWSEXJGSoT6QmwFBuFCNyq5taW11_co2JbkH-3w
2
# 数据交互
用户登录 -> 后端验证登录返回 token -> 前端带上token请求后端数据 -> 后端返回数据,
数据交互流程如下:

# 权限注解
Spring Security 提供了Spring EL表达式,允许我们在定义接口访问的方法上面添加注解,来控制访问权限,常用的 EL如下
| 表达式 | 描述 |
|---|---|
| hasRole([role]) | 当前用户是否拥有指定角色 |
| hasAnyRole([role1,role2]) | 多个角色是一个以逗号进行分隔的字符串。如果当前用户拥有指定角色中的任意一个则返回true |
下面的接口表示用户拥有 admin、menu:edit 权限中的任意一个就能能访问modifyMenuById方法,
如果方法不加@preAuthorize注解,意味着所有用户都需要带上有效的 token 后能访问 modifyMenuById 方法
@ApiOperation("修改菜单")
@PostMapping(value = "/modifyMenuById")
@PreAuthorize("hasAnyRole('admin','menu:edit')")
public ResponseEntity<Void> modifyMenuById(@Validated(SystemMenuTb.Update.class) @RequestBody SystemMenuTb args) {
systemMenuService.modifyMenuById(args);
return ResponseEntity.ok(null);
}
2
3
4
5
6
7
由于每个接口都需要给超级管理员放行,而使用 hasAnyRole('admin','user:list') 每次都需要重复的添加 admin 权限,因此在新版本中加入了自定义权限验证方式,在验证的时候默认给拥有admin权限的用户放行。
源码:
// cutejava-module-system -> cn.odboy.system.framework.permission.config.AuthorityConfig
@Service(value = "el")
public class AuthorityConfig {
/**
* 判断接口是否有权限
*
* @param permissions 权限
* @return /
*/
public Boolean check(String... permissions) {
// 获取当前用户的所有权限
List<String> roleList = CsSecurityHelper.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
// 判断当前用户的所有权限是否包含接口上定义的权限
return roleList.contains("admin") || Arrays.stream(permissions).anyMatch(roleList::contains);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
使用方式:
@PreAuthorize("@el.check('user:list','user:add')")
# 接口放行
在我们使用的时候,有些接口是不需要验证权限的,这个时候就需要我们给接口放行,使用方式如下
1、使用注解方式
只需要在Controller的方法上加入该注解即可
@AnonymousAccess
2、修改配置文件方式
cutejava-module-system -> cn.odboy.system.framework.permission.config.SpringSecurityConfig
提示
使用 permitAll() 方法所有人都能访问,包括带上 token 访问
使用 anonymous() 所有人都能访问,但是带上 token 访问后会报错