Vue + Spring Boot 项目实战(十二):访问控制及其实现思路

前言

上篇文章「Vue + Spring Boot 项目实战(十一):用户角色权限管理模块设计」被推荐了,emmmmm,果然这种画大饼的文章容易被翻牌子,然鹅我都没敢把它当一个新的系列,就是怕被催更。好在一个中午过后我就凉了,又混了一周,现在又为了排名被迫营业啦。

这两天做了一件挺有意思的事,规划了下未来 5 年的理财方案,这 5 年应该是比较重要的,涉及到结婚、买房、买车、子女养育等一系列问题。相比同龄人,我和女朋友应该算是比较早着手计划这些事的,过去两年是一个探索,接下来心里就比较有底了。可以跟大家透露一下,我们现在的小目标是攒够首付在深圳上车,基本不需要什么努力。我的另一个小目标是 5 年内年入百万,这个嘛,大家一起见证吧。我只是一个普通人,现在的信仰就是大力出奇迹,如果我实现了这个小目标,希望能给大家一些正面的激励,不要觉得生活没有希望,敢想敢做敢坚持,干就完事了。

好了,进入正题。这篇文章的目的,主要是在正式开发之前做一个铺垫,把功能实现的逻辑讲清,让大家有一个基本的思路。

一、基础知识

1.关于 RBAC

“用户-角色-权限”管理是 “访问控制” 的一种实现方式,更为专业的叫法为 RBAC(Role-Based Access Control),即基于角色的权限访问控制。不少地方提到RBAC 具有三个特性,或者说支持三个原则:最小权限原则,责任分离原则和数据抽象原则,这玩意儿就是骚话,没什么实际意义,有兴趣的自行百度(如果有面试的问这种问题,只能说明他是个瓜皮)。

我觉得关于 RBAC,最重要的是理解为什么要在用户和权限之间加上角色这一层,而不是直接把权限赋给用户。这个问题一点也不难,考虑需要修改用户权限的情形,给一两个用户设置权限没什么问题,但如果有成千上万个用户需要同时获取或去除同一个权限,那可费老劲了,但通过角色来完成这个工作就十分便捷。这实际上也是一种 “解耦” 的思路。

目前对于访问权限的控制几乎全部采用这种方式,差异在于能实现到什么程度。上篇文章提到过权限的三种粒度:菜单权限、操作/功能权限、数据权限。此外还有一些额外的功能,比如互斥性检验(一个角色不能同时拥有两种互斥的权限)、角色继承(新建角色时继承某一角色的权限)等。

2.Shiro简介

Java Web 可以选用的安全框架主要有两种:Spring SecurityShiro

原本我是想用 Spring Security 的,但为了多保住几根头发,选择了讲起来比较容易的 Shiro。总体来说前者功能更全面一些,但 Shiro 也完全够用了。

Shiro 是一个强大且易用的 Java 安全框架,可以用来实现身份验证(authentication)、授权(authorization)、加密(cryptography)和会话管理(session managment),下面是号称简单易学的官方文档:

http://shiro.apache.org/documentation.html

利用 Shiro ,我们可以更轻松地实现权限控制功能,同时为我们的项目构建完整的安全体系。在我更新之前,大家可以参照下面这个实践教程做一下预热:

「How2J.CN - Shiro 教程」

二、实现思路

1.菜单权限

对菜单的权限控制是最常见的。

在后台管理中,这个菜单通常表现为一个单独的页面,拥有自己的 URL 或路由。拿我们的项目举例,假如我想控制用户对不同页面的访问,应该怎么做呢?

思路如下:

  • 使用 “全局前置守卫”(router.beforeEach),在导航触发时向后端发送一个包含用户信息的请求
  • 后端查询数据库中该用户可以访问的菜单(也就是 vue 的路由信息)并返回
  • 前端把接收到的数据添加到路由里,并根据新的路由表动态渲染出导航栏,使不同用户登录后看到不同的菜单。同时,由于路由表也是按需加载的,所以用户也无法通过 URL 访问没有权限的页面

演示效果如下:

(系统管理员登录时加载所有导航)
系统管理员登录时加载所有导航
(普通用户登录时不加载用户管理模块)
普通用户登录时不加载用户管理模块
这是前后端分离的思路,传统项目实现起来更为简单:

  • 利用过滤器,如果用户有权限则返回需要访问的页面,没有则返回未授权页面
  • 菜单的动态渲染利用模板的常规功能即可实现,与 Vue 类似

2.功能权限

所谓功能,反映在前端就是一个组件,比如按钮或图表,在后端就是一个接口。其实现逻辑与对菜单的控制类似,只是触发的时机不同。

思路一: 按权限加载组件。即在渲染页面前向后端发送请求,获取有权限使用的组件并动态渲染,并在需要调用后端接口时进行判断,防止用户通过自行构造请求的方式绕过限制

思路二: 不管三七二十一前端组件全部加载出来,但需要调用后端接口时进行判断,如果无权限则弹出相应提示。这种适合对按钮的控制,图表直接不加载数据就显得不是很友好

演示效果如下:

(拥有权限的用户可正常使用添加角色功能)
拥有权限的用户可正常使用添加角色功能
(无权限的用户点击按钮会弹出提示)
在这里插入图片描述
哈哈,我之前做的就是图省事的版本,为了讲解我就把第一种思路也实现一下吧。不过在实际开发中要本着够用就行的原则,能用简单的方法实现功能当然要选简单的。

3.数据权限

之前提到过,数据权限也有两个层次,一是对可访问性的控制,二是对数据量的控制。

可访问性可以针对表、字段或满足某些条件的数据。针对表、字段的控制,主要依靠在业务逻辑执行前进行判断,比如在调用对收支信息表的查询前判断当前用户是否具有财务权限。而访问特定数据,可以直接通过 SQL 语句(WHERE 条件)来实现,比如当前用户只能查询出自身拥有的书籍,就可以通过类似 SELECT * FROM book WHERE uid = #{uid} 的语句来实现。

对数据量的控制比较五花八门,常见的比如一天内普通用户只能访问 2000 条数据(公众号好像就有这个限制),可以通过引入计数机制来实现,调用接口或执行业务逻辑时先进行判断,同时限制本次查询的最大数量。此外,还有需要对一次的访问量进行控制、对某段时间能够处理的数据量进行控制等应用场景等等,不再赘述。

下一步

这个,众所周知,祖国母亲马上生日了,为了给她庆生,我得回一趟老家,所以下周恐怕要销声匿迹了。好在我本来也没活跃过,所以大家可能感觉不到。祝各位老铁生活愉快哈~

查看系列文章目录:
https://learner.blog.csdn.net/article/details/88925013

上一篇:Vue + Spring Boot 项目实战(十一):用户角色权限管理模块设计

下一篇:Vue + Spring Boot 项目实战(十三):使用 Shiro 实现用户信息加密与登录认证

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页