最新Spring Security实战教程(六)基于数据库的ABAC属性权限模型实战开发
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》专栏19年编写主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
🌛《开源项目》本专栏主要介绍目前热门的开源项目,带大家快速了解并轻松上手使用
✨《开发技巧》本专栏包含了各种系统的设计原理以及注意事项,并分享一些日常开发的功能小技巧
💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程
🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整
🌞《Spring Security》专栏中我们将逐步深入Spring Security的各个技术细节,带你从入门到精通,全面掌握这一安全技术
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~
最新Spring Security实战教程(六)基于数据库的ABAC属性权限模型实战开发
- 1. 前言
- 2. 权限决策依据
- RBAC
- ABAC
- 综合对比
- 3. 数据库表结构说明
- 4. 实战开始
- 5. MyBatis-Plus实体定义
- ❶ 用户实体(实现UserDetails)
- ❷ 角色实体
- ❸ 菜单实体
- ❹ 用户属性实体
- ❺ 决策表实体
- 6. MyBatis-Plus Mapper配置
- 7. 自定义UserDetailsService实现
- 8. 实现方式一:自定义MethodSecurityExpressionHandler
- 9. 实现方式二:自定义注解
- 10. Spring Security配置文件
- 11. controller测试文件
- 12. 完整工作流程
- 14. 总结
回顾链接:
最新Spring Security实战教程(一)初识Spring Security安全框架
最新Spring Security实战教程(二)表单登录定制到处理逻辑的深度改造
最新Spring Security实战教程(三)Spring Security 的底层原理解析
最新Spring Security实战教程(四)基于内存的用户认证
最新Spring Security实战教程(五)基于数据库的动态用户认证传统RBAC角色模型实战开发
专栏更新完毕后,博主将会上传所有章节代码到CSDN资源免费给大家下载,如你不想等后续章节代码需提前获取,可以私信或留言!
1. 前言
今天博主又抽空来给小伙伴更新 Spring Security 教程啦,上个章节中我们讲解了如何通过数据库实现基于数据库的动态用户认证,大家可能发现了,项目中是基于RBAC角色模型的权限控制,虽然能满足大多数场景,但在面对复杂、细粒度的权限需求时可能会力不从心。基于属性的访问控制(ABAC)模型则通过评估用户、资源、环境等多种属性,实现更加灵活的权限控制。
例如,某个菜单的访问可能不仅取决于用户角色,还取决于用户的部门、时间或其他属性。因此,需要在权限验证时动态获取这些属性,并进行评估。那么本章节我们就来讲解基于数据库的ABAC属性权限模型实战开发
2. 权限决策依据
既然谈到了 RBAC 和 ABAC 两个模型,就大家介绍下两者间的区别:
RBAC
- 核心思想:以角色作为权限管理的核心,每个用户被赋予一个或多个角色,而角色与权限之间存在固定的映射关系。
- 决策依据:当用户请求访问资源时,系统根据用户所属角色所拥有的权限进行校验。
- 粒度:粒度相对较粗,因为权限是绑定在角色上的,无法针对单个请求条件进行动态决策。
ABAC
- 核心思想:以属性(Attribute)为基础,利用用户属性、资源属性、环境属性等多个维度的条件进行权限判断。
- 决策依据:权限决策是基于各种属性之间的逻辑表达式和策略规则来动态确定是否允许访问。
- 粒度:支持非常细粒度的控制,可以针对具体属性制定规则,实现精准的权限控制。
综合对比
对比维度 RBAC ABAC 决策依据 用户所属角色与预定义权限映射关系 用户、资源及环境属性和策略规则 灵活性 固定、静态权限模型 动态、可扩展的权限决策模型 管理难度 管理较简单,但角色关系复杂时易混乱 规则管理复杂,但扩展灵活 粒度 较粗,难以细化至个性化条件 非常细粒度,可实现精确权限控制 适用场景 企业内部、权限固定的系统 复杂、多变、动态决策的业务系统 3. 数据库表结构说明
上一个章节RBAC角色模型我们使用了五张表,sys_user 、 sys_role、 sys_user_role 、sys_menu 、 sys_role_menu ,需要数据表结构的小伙伴可以查阅上一章内容!本章节不再赘述
现在我们在传统RBAC模型基础上,加入ABAC属性权限模型 ABAC(Attribute-Based Access Control)引入了更细粒度的动态控制维度:
为什么要增加ABAC属性权限模型?
需求1:请求某个方法除了要验证用户角色或菜单资源,我还要判断用户属性部门=IT,国家是ZH
需求2:请求某个方法除了要验证用户角色或菜单资源,我还要限制访问时间段
而如果使用ABAC属性权限模型动态策略就可以很轻松解决这样的问题!
基于上述的需求,我们来扩展我们的数据库表,sys_user_attr 为用户相关属性,sys_policy 为策略表(ABAC规则存储)
-- 扩展用户属性表(新增) CREATE TABLE sys_user_attr ( user_id BIGINT NOT NULL, attr_key VARCHAR(50) NOT NULL, attr_value VARCHAR(100) NOT NULL, PRIMARY KEY (user_id, attr_key) ); -- 示例数据 INSERT INTO sys_user_attr VALUES (1, 'department', 'IT'), (2, 'department', 'HR'), (3, 'security_level', '3'); (1, 'country', 'zh'),
权限策略表设计:
存储 ABAC 策略,每条策略包含一个条件表达式(基于 SpEL 编写)
CREATE TABLE sys_policy ( policy_id BIGINT AUTO_INCREMENT PRIMARY KEY, policy_name VARCHAR(50) NOT NULL, target_resource VARCHAR(64) NOT NULL, condition_expression VARCHAR(255) NOT NULL ); INSERT INTO sys_policy VALUES (1, 'IT部门访问策略', 'admin:menu', "#user.attrs['department'] == 'IT'"), (2, '高安全级别策略', 'developers:menu', "T(Integer).parseInt(#user.attrs['security_level']) >= 3"); (3, 'IT部门访问策略', 'admin:menu', "#user.attrs['country'] == 'zh'");
整体数据库结构如下:
4. 实战开始
接下来在之前的 Maven 项目中,我们复用上个章节的子模块并命名 abac-spring-security
由于涉及数据库操作以及整合mybatis-plus,上一章节博主已经进行了配置的详解这里就简单贴出代码供大家参考:
org.projectlombok lombok provided org.springframework.boot spring-boot-starter-data-jpa mysql mysql-connector-java 8.0.30 com.baomidou mybatis-plus-spring-boot3-starter 3.5.9
配置yml文件,运行项目确保项目能正常链接数据库且启动成功
server: port: 8084 spring: application: name: db-spring-security #最新Spring Security实战教程(六)基于数据库的ABAC属性权限模型实战开发 datasource: url: jdbc:mysql://localhost:3306/slave_db?useSSL=false&serverTimezone=UTC username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver hikari: maximum-pool-size: 5 mybatis-plus: configuration: map-underscore-to-camel-case: true # 开启驼峰转换 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印SQL cache-enabled: true # 开启二级缓存 global-config: db-config: logic-delete-field: delFlag # 逻辑删除字段 logic-delete-value: 1 # 删除值 logic-not-delete-value: 0 # 未删除值
5. MyBatis-Plus实体定义
接下来我们开始编写业务代码
❶ 用户实体(实现UserDetails)
@Data @TableName("sys_user") public class SysUser implements UserDetails { @TableId(type = IdType.AUTO) private Long userId; @TableField("login_name") private String username; // Spring Security认证使用的字段 private String password; private String status; // 状态(0正常 1锁定) private String delFlag; // 删除标志(0代表存在 1代表删除) @TableField(exist = false) private List roles; @TableField(exist = false) private Map attrs; // 用户的属性集合,用于 ABAC 动态权限评估 // 实现UserDetails接口 @Override public Collection