1. 需求描述

最近在梳理springboot前后端分离后的权限管理问题。前段时间,已经把shiro的实现和spring security 的实现进行了初步的了解。如果深入细节,一个篇幅怕是不够。本文仅对权限管理的一些通用原理进行探讨。

2. 权限分类

在前后端分离之后,对于权限方面,主要存在两方面的权限:(1)前端页面访问权限,(2)后台接口访问权限。下面分别以页面权限和接口权限两个方面展开讨论。

3. 页面权限管理

页面权限管理,即前端的不同页面需要不同的页面访问权限,比如,某一个页面A,需要超级管理员才能访问;某一个页面B,需要管理员才能访问;某一个页面C,普通注册用户就能访问;某一个页面D,不需要认证就能访问。从这里,我们可以抽象出几个最基本的概念。某一个用户,拥有若干角色;而某一个角色能够访问若干页面。在数据库层面,对应了几张表,即 用户表,用户角色表,角色表,角色菜单表,菜单表
那么,如何实现呢?
在回答这个问题之前,可以参考以下几篇文章:
(1)
Vue动态加载组件的两类方式(import和require)
(2) Vue动态路由的后端实现(基于AOP的思路)
(3) Vue动态路由的前端实现
从这几篇文章中,不难发现。页面可以通过动态路由的方式来渲染。再结合上权限,很自然的想到了解决方案。即某一个用户登录认证成功后,一方面会返回一个token作为后续访问的凭证,另一方面,同时查询数据库,返回该用户角色对应的菜单列表。不同的用户,拥有不同的菜单列表。
某个用户的菜单列表返回前端后,在前端完成渲染,从而达到了页面权限管理的作用。当然,再细粒度一点,也是可以做的,即在页面中,某一个组件的渲染,也采用动态渲染的方式,即把该组件对应的渲染权限保存在数据库中,用户登录的时候,随着user对象一同返回前端,完成渲染。不过,页面权限和页面内组件权限,通常是两个不同层面的解决方案。思想是相通的。如果某个页面,限制某个角色才能访问,通常,该页面也就不对页面内组件再进行角色权限分配了(虽然可以实现,但明显增加了复杂性)。因为如果对页面内组件进行角色权限分配,就没有必要再对该页面进行上一层的可访问性动态渲染控制。 通常情况下,某一个具体的页面权限控制,是从该两种方案中二选一的关系。即要么进行该页面的动态渲染,某些用户角色可以访问该页面,某些用户角色不能够访问该页面。要么对该页面内的组件进行权限控制,某些用户角色能够访问该页面内的某些组件,某些用户角色不能够访问该页面内的某些组件。
如果只进行了页面权限控制,而对后台接口没有进行权限限制。那么,如果一个用户登录系统后,通过该用户凭证,就可以无限制的访问后台接口(因为后台接口仅需要完成认证),通过模拟的浏览器软件,进行接口操作,可能会给系统带来很大的安全隐患。
那么,就得对后台的接口进行权限控制,以下将展开讨论。

4. 接口权限管理

这里的接口权限管理,主要指springboot中的后台接口的授权访问权限。那么,如何实现呢?
某一个用户登录的时候,会携带该用户名(用户id)以及密码(或是验证码)在后台完成密码比对,或是验证码比对,确认身份成功后(即认证成功后)会返回一个token信息,作为该用户的一个凭证返回前台,前台保存该用户的token信息,以后访问接口,携带该token进行访问。
在后台,该用户登录完成认证后,系统会查询数据库,获取该用户的角色列表,以及该角色列表对应的可访问接口的权限列表。后台把该用户的角色列表,以及对应权限列表注入spring容器里面。具体管理角色权限方式,可以用shiro,当然,也可以用spring security。在此基础之上, 某一个用户登录,系统中就会保存该用户的角色列表,以及对应的权限列表。
但是,后台的接口权限验证方式,通常并不是对所有的接口都进行权限验证,比如,登录就是对所有的用户都可以访问的接口。如果用 集合A 来表示所有的接口集, 集合B 来表示需要权限才能够访问的接口集。显然,集合B 是集合A的 真子集。即在数据库中,需要保存一份集合B,即 权限表。 这里可以做这样一个假定,假定 接口 和 权限 存在 1:1的关系,事实上,他们也是一对一的关系,因为这里从定义就可以看出,这里研究的就是接口的权限,一个接口就有一个接口的权限。 那么,在权限表(接口权限表)中,我们就可以把涉及到需要权限才能够访问的接口存在 权限表 中。
而仅有权限表也是不够的,我们还需要 角色权限表 ,即某一个用户角色可以访问权限表中的一个 子集C 。另一个用户角色可以访问权限表中的另一个 子集D
回到刚才的话题, 某一个用户登录,系统中就会保存该用户的角色列表,以及对应的权限列表。
那么,某一个用户登录认证成功后,再次访问其他接口的时候,如何判断该接口是需要授权才能够访问呢,还是不需要授权就可以访问。 在这里,有几种方案可供选择,这也是本文探讨的重点。主要有以下两种实现方式:
(1) 在某一个接口上标明一个注解,表示该接口需要什么角色才能够访问,或者,该接口需要什么权限才能访问。那么,对于登录的用户,shiro或者spring security 会帮我们判断,该用户是否拥有该角色或是否拥有该权限,从而是通过该访问请求,还是拒绝该访问请求,当然,这个工作,也可以自己写一个切面去实现。
但是,这种方式存在一个缺点,就是接口的权限,无法一目了然的统一管理。即我们需要去翻阅代码,才知道哪个接口上标注了权限注解,哪个接口上没有标注权限注解。数据库中的权限表(接口权限表)中的权限,并不一定要全部标注在接口上。可能会有预留的情况。
(2) 另一种方式是,接口上不添加注解。系统中保存一份需要权限访问的接口列表(从数据库查询)。即权限表中保存的是需要权限才能访问的所有接口列表。
从上得知, 某一个用户登录,系统中就会保存该用户的角色列表,以及对应的权限列表。 即保存了该用户对应的可以访问的接口权限列表。
那么,当该登录用户访问其他接口的时候,用aop拦截,判断该接口是否在需要权限才能访问的接口里面。如果不在,则通行;如果在,再判断该用户有没有该接口的权限。如果没有,则抛出没有权限的异常返回。如果有,则通行。
(3) 当然,在这里还有另一种判断选择。同样接口上不添加注解。但在shiro或是spring security中注入的不是该用户拥有的接口权限,而是该用户被拒绝的接口权限。即在该用户登录的时候,在后台查询数据库,根据该用户拥有的权限接口,以及所有需要权限才能访问的接口,获取需要权限但该用户没有权限的接口,即该用户不能访问的权限接口。
在该用户访问其他接口的时候,在aop里面,判断该访问的接口是不是在拒绝权限的接口里面,如果是,则拒绝访问,否则,则通行。

以上三种方式,各有优缺点,在此不再展开。后续探讨后,再开篇幅进一步探讨权限相关的内容。

5. 结语

java后台开发,权限的重要性不言而喻。但参阅相关的博客发现,大多数的文章仅说明,shiro或是spring security的具体实现。而对其抽象的基本原理没有进行较好的描述,本文就是为了从抽象的角度,来描述springboot前后端分离后权限的实现原理,以及不同的算法选择。

6. 参考资源

(1) Vue动态加载组件的两类方式(import和require)
(2) Vue动态路由的后端实现(基于AOP的思路)
(3) Vue动态路由的前端实现

1. 需求描述最近在梳理springboot前后端分离后的权限管理问题。前段时间,已经把shiro的实现和spring security 的实现进行了初步的了解。如果深入细节,一个篇幅怕是不够。本文仅对权限管理的一些通用原理进行探讨。2. 权限分类在前后端分离之后,对于权限方面,主要存在两方面的权限:(1)前端页面访问权限,(2)后台接口访问权限。下面分别以页面权限和接口权限两个方面展开讨论。3. 页面权限管理页面权限管理,即前端的不同页面需要不同的页面访问权限,比如,某一个页面A,需要超级管理员
适用人群所有的IT从业者,尤其适合快速掌握新技术,快速增长工作经验人群,对教育公平,教育公益,教育爱心公益人士课程概述该互联网实战项目是基于 Spring Boot 2+ SpringSecurity5+Element UI+Vue Admin Template+蚂蚁可视化AntV 等技术栈开发的项目,采用分布式,多模块, 前后端分离 开发。包括图形展示、 权限 管理、用户管理等功能。【后端技术】技术说明Spring Boot2MVC框架 开发的一站式解决方案Spring Security5 认证和授权框架MyBatisPlus3.3.1 基于 MyBatis 框架的快速研发框架MyBatisCode工具生成 MyBatis 相关代码Jackson提供了处理 JSON 数据的工具Lombok简化对象封装工具 Druid   数据库连接池 【前端技术】Vue       互联网最火的前端框架Vue Router路由框架Vuex全局状态管理框架Axios前端 HTTP 框架Element UI前端 UI 框架Vue Element Admin前端模板Antv  蚂蚁金服可视化技术,阿里巴巴可视化技术,天猫,淘宝,支付宝,花呗均使用AntV【开发工具】IntelliJ IDEA开发 IDESQLyog数据库连接客户端PostmanHTTP 请求工具【开发环境】工具版本JDK1.8MySQL5.7
太久没写了,今天补一篇,本篇无实际代码,主要是设计思路。 关于JWT:在我所开发的系统中用户Token都是有意义的,都会携带部分数据,不过多用于userId 个人的 权限 系统使用历程: 基于Security(不加表、角色放在Token中) 注解验证(乱七八糟) 使用Spring Security框架,将用户角色ROLE_USER写在account表中,UserDetailsService的实现方法中封装UserDetails返回,然后在接口上添加注解进行 权限 校验 好处是简单,但是 权限 写在逻辑里面了。改 权限
Spring Boot是一个构建微服务的框架,可以方便地实现 前后端分离 前后端分离 是指将前端和后端分离开来开发,前端只负责页面展示和用户交互,后端只负责数据处理和业务逻辑。 实现 前后端分离 的步骤如下: 1. 前端代码和后端代码分别存放在 不同 的项目中。 2. 配置前端和后端的跨域设置。 3. 前端发送请求到后端时,后端返回JSON格式的数据,前端解析JSON数据并展示。 4. 前端通过RESTful API(即HTTP的GET、POST、PUT、DELETE等请求)与后端交互。 5. 后端通过Spring Boot提供的@RestController注解实现RESTful API。 6. 前端与后端的交互可以通过Axios等HTTP库实现。 通过以上步骤,可以实现 前后端分离 ,让前端和后端的开发者分别专注于自己的领域,提高开发效率。
一定要坚持创作更多高质量博客哦, 小小红包, 以资鼓励, 更多创作活动请看: 程序员有哪些绝对不能踩的坑?: https://activity.csdn.net/creatActivity?id=10433?utm_source=csdn_ai_ada_redpacket 新星计划2023: https://marketing.csdn.net/p/1738cda78d47b2ebb920916aab7c3584?utm_source=csdn_ai_ada_redpacket 如何入门Python: https://activity.csdn.net/creatActivity?id=10436?utm_source=csdn_ai_ada_redpacket 全部创作活动: https://mp.csdn.net/mp_blog/manage/creative?utm_source=csdn_ai_ada_redpacket BBAA9527: 请问我按照你的步骤配置的SpringSecurityConfig,项目build的时候会报错 java: 无法访问javax.servlet.Filter 找不到javax.servlet.Filter的类文件 您遇到过吗 Springboot整合activiti7(排除springSecurity版) lxh.lcl: 类似bpmnjs Vue动态路由的前端实现 我是隔壁老王呀: