# 系统权限

本工程主要包含两方面的权限概念。

一个是菜单权限,一个是接口权限。

其中菜单权限是必须的,接口权限在个别要求不严谨的项目中,可以放低要求。接口权限主要用于控制API接口安全,防范部分黑客绕过你的WEB页面,直接向API发起越权漏洞攻击。

权限架构体系采用业内主流的RBAC架构。

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

# 菜单权限

# 菜单维护

要控制菜单的权限,首先你需要建立起你自己的菜单体系。这个可以在WEB页中的系统维护 > 菜单列表进行维护。

菜单列表是树形结构。新增页面如下图所示:

提示

  1. 图标指的是左侧菜单中需要显示的图标

  2. 动作中,单页面模式指的是直接在当前页打开,这也是最常用的模式,一般选择默认即可。多页模式指的是在新页面打开,类似于a标签target="_blank"

  3. 菜单名称指的是左侧菜单中显示的文字

  4. 跳转地址:

    路由名称:使用Vue Route中命名的路由名称进行跳转。

    路由地址:使用可以直接在浏览器地址栏看到的,跟在哈希(#)后的URI地址进行跳转。

    外部链接:可以使用全限定URI进行跳转,通常配合多页模式

# 给角色赋予菜单权限

接下来打开WEB页的系统维护 > 角色列表,在你需要配置的角色右侧点击菜单按钮,继续在里面勾选需要查看的菜单即可。

# 接口权限

# 权限维护

要控制接口权限,首先你需要维护好自己的接口权限。打开系统维护 > 权限列表。如下图所示。

接口权限也是树形结构的,但却不一定要遵守这个约定,你也可以维护成一维的。

怎么理解这句话呢?

场景1: 如果你要删除用户,那么正常来讲你也必须拥有查看用户列表的权限。这样他们就组成了父子关系,有子(删除用户权限)那必定就有父(查看用户列表权限)。这时候你可以遵守树形约定。

场景2: 如果你要删除用户,但却不是在用户列表中进行操作。比如:你自己定义了一个页面,输入用户名称即可对该用户进行删除操作,这时候,实际上你不一定需要查看用户列表这个权限。所以这时候你可以不维护成树形约定。

总之,对于如何维护权限,暂时没有强制要求你怎么做。最简单的当然是不采用树形维护。只不过有个缺点,就是当权限多的时候,权限之间会产生一种无关联性,看上去会比较凌乱。

所以我建议你充分使用排序和描述两个字段。

描述的命名建议使用模块:权限名称这种方式来命名,比如用户:删除用户:禁用。这样会显得比较整齐。

提示

关于排序(其他模块通用):

不建议你直接使用1,2,3,4,...,20这种连续方式维护。

你可以这样,比如用户权限是一个区间(1-100),菜单权限是另一个区间(101-200),依此类推。也就是不同模块间的间隔至少为100。

如果你第一次给用户权限维护了增删改查4个接口权限(排序分别为101,102,103,104),后来你又需要新增一个用户禁用的接口权限,你可以使用排序105。

这样做的好处就是,你可以保证同一模块的接口权限永远都排列在一起。

接下来,我们看下权限的新增页面。

权限名称:用于显示在列表中,取个合理的名称即可。

重点来看下对象操作

这两个属性是需要映射到API中的。权限框架采用的是Spring Security

如果你有接触过Apache Shiro,应该知道shiro的接口授权可以使用角色权限两种。

但是我们已经有了自己的RBAC体系,所以我这边将其简化了,我们只使用权限标识符来进行用户的授权。因为有了用户的角色,我们可以很方便的推导出该用户的所有权限。

权限标识符的结构为对象:操作,比如demo:delete,表示demo的删除权限。所以,你只需要在对象属性中填写demo,在操作属性中填写delete即可。

# API设定权限标识符

当然最重要的是,打开你的Conreoller,找到你的删除接口,加上下述注解:








 





@ApiOperationSupport(author = "luosz@jfbrother.com", order = 7)
	@ApiOperation(value = "示例表删除", notes = "示例表删除接口")
	@ApiVersion(1)
	@ApiImplicitParams({
		@ApiImplicitParam(name = "ids", value = "主键id", required = true, dataType = "string", allowMultiple = true)
	})
	@DeleteMapping
	@RolesAllowed({"demo:delete"})
	public Result delete(@RequestBody @NotNull(message = "示例表id列表不能为空") @Size(min = 1, message = "示例表id至少存在一个") List<String> ids) {
		service.delete(ids);
		return ResultGenerator.genSuccessResult(ResultCode.NO_CONTENT);
	}
1
2
3
4
5
6
7
8
9
10
11
12

注意

  1. RolesAllowed注解支持数组,也就是说可以维护多个权限标识符,如下表示拥有删除和更新的任意一种权限都可以访问该接口。
@RolesAllowed({"demo:delete","demo:update"})
1
  1. 很多情况下,同一个权限标识符是可以重用的。比如用户的列表查看接口用户的单目录查看接口均可赋值为同一个标识符user:query

可以看出具体的API接口和WEB上的权限实际上并不是一一对应的,他们的桥梁就是权限标识符,标识符的维护是很灵活的,具体要看具体的业务情况来定。

总之,记住授权的原理:

根据当前登录用户查询角色,通过角色获得所有的权限标识符,访问接口时,Spring Security会自动分析,接口所需权限标识符是否在所有的权限标识符

# 给角色赋予接口权限

接下来打开WEB页的系统维护 > 角色列表,在你需要配置的角色右侧点击权限按钮,继续在里面勾选需要查看的权限即可。

最后一次更新: 2021-6-2 16:28:35