后端鉴权(认证授权)
RBAC权限模型
概述
在企业系统中,通过配置用户的功能权限可以实现让不同的人分管不同业务的需求。RBAC(Role Based Access Control)模型,中文是基于角色的访问控制,主要是将一组功能组合成一个角色,再将角色分配给用户,也就是说角色是功能的合集
比如:
企业A总共有12个功能,包括财务管理、人事管理、销售管理等等,如果不引入 RBAC 模型,咱们就需要每创建一个用户就要分配一次功能,假设企业A有100个用户,这将至少需要进行100次操作。如果用户数量增加到1000甚至10000,并且一个用户可能会拥有多个功能,操作将会变得非常繁琐。如图:

经过多次操作后发现,有些人被分配了相同的功能。例如,A、B等10个用户都被分配了客户管理、订单管理和供应商管理这几个模块。**将这几个功能模块组合成一个包,然后将整个包分配给需要的用户,这个包被称为角色**。由于角色和功能之间的对应关系相对稳定,在给用户分配权限时只需分配角色即可,如下图所示:

基于RBAC授权后,咱们可以达成以下2个目标:
- 解耦用户和功能,降低操作错误率
- 降低功能权限分配的繁琐程度

ER图与关系梳理
在一个核心业务系统中,通常通过业务分析,从而抽离出数据库表,表确定之后会进一步分析表中应该有的字段,下面先看一份业务ER图:

上图中清楚的描述用户、角色、资源、职位、部门之间的关系,同时咱们进一步推导出以下结果:
- 用户与职位是N:N关系
- 用户与部门是N:1关系
- 用户与角色是N:N关系
- 角色与资源是N:N关系
- 部门与角色是N:N关系
表关系(简图)

Spring Security
概述
Spring Security是一个基于Spring框架的安全解决方案,它为应用程序提供了完整的安全管理功能,包括认证、授权、攻击防范和会话管理等
官网地址:Spring Security
Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.
Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements
在若依系统中,已经集成了Spring Security安全框架
核心作用
用一张图来说明一下spring Security的核心作用

- 登录请求
- 校验验证码是否正确
- 通过spring security框架验证用户是否存在,密码是否正确
- 查询用户所拥有的权限列表
- 最后把用户信息封装到jwt生成的token中返回
- 其他请求(可以是非登录的任意请求),这些校验工作可以全部交给Spring Security来完成
- url是否需要检验(访问接口是否需要放行,比如登录、注册、验证码这些接口;还有一些静态资源也需要放行,比如html、js、css等)
- token校验,是否为空,是否过期,是否正常解析
- 校验当前访问的url与当前用户的权限是否匹配,匹配则放行,不匹配则是权限不足
权限控制
认证
认证(Authentication)
认证是用户登录系统时,通过比较用户提供的凭证(如用户名和密码)与系统中存储的信息是否一致,以验证用户身份是否有效的过程
当前系统的认证流程:

代码入口:zzyl-admin模块下找到:com.zzyl.web.controller.system.SysLoginController.login()
授权
授权(Authorization):
- 授权就是用户登录后(认证后),控制用户是否有权限访问某些资源。
- 下图是给用户赋予角色,并且可以可以赋予多个角色

下图中,可以给角色赋予多个功能权限

下图中,可以对菜单和按钮进行权限标识的配置

权限验证
一个请求过来之后,需要有诸多的校验来能判断是否能有效访问
- 请求来了以后,如果是
doc.html或login,是一个静态资源,可以直接放行,在SecurityConfig可以配置放行接口 - 请求来了以后,如果是
/nursing/elder/save,在SecurityConfig没有配置放行,需要校验当前请求携带的token是否有效,如果token无效,则是认证失败,需要重新认证(跳转到登录页) - 请求来了以后,如果是
/nursing/elder/save,在SecurityConfig没有配置放行,token也有效,则判断当前登录人是否拥有该权限(认证成功后,可以获取用户的权限列表)- 如果有权限,则放行
- 如果没权限,则提醒权限不足
核心代码位置:在zzyl-framework模块中找到类:com.zzyl.framework.config.SecurityConfig
1 | /** |
具体的 url 校验是通过 Spring Security 的提供的权限注解@PreAuthorize实现的,可以判断具体的url是否有权限访问该接口
- @PreAuthorize 是 Spring Security 框架中提供的一个安全注解,用于实现基于注解的访问控制。它允许开发者在方法级别上声明特定的安全约束,以确保只有满足指定条件的用户才能调用该方法
- 当 @PreAuthorize 注解被应用于某个方法时,Spring Security 在该方法执行前会先对当前认证的用户进行权限检查。如果检查通过,方法调用得以继续;否则,框架会抛出相应的权限异常(如 AccessDeniedException),阻止方法执行
- 若依框架生成的Controller中都可以见到权限控制的代码,如下:
1 |
|
- @PreAuthorize Spring Security 框架的权限注解,在执行方法前执行
- 已经开启注解生效,在SecurityConfig类中添加了如下注解:
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)- @ss.hasPermi(‘system:user:list’)
- 其中的ss是一个被spring管理的bean
- 位置:zzyl-framework模块中的
com.zzyl.framework.web.service.PermissionService- hasPermi 是
PermissionService类中的一个方法,判断是否拥有该权限- system:user:list 为方法的参数
- 权限控制的流程
