news 2026/4/23 6:57:56

数据中台权限设计

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
数据中台权限设计

结合(Spring Security + MyBatis-Plus)以及数据中台的通用架构,梳理了一套完整的权限设计方案,包含架构分层、核心设计以及时序交互流程。

🏗️ 一、 整体架构设计

在数据中台中,权限体系通常分为三个维度,你提到的这三者各司其职:

  1. 功能权限 (Spring Security):控制“你能看什么页面、点什么按钮”。基于 RBAC(基于角色的访问控制)模型,通过菜单和按钮权限控制前端界面的可见性。
  2. 项目权限 (MyBatis-Plus):控制“你能进哪个项目”。数据中台通常涉及多项目隔离,通过拦截 SQL,在查询项目相关数据时自动注入project_id = X的过滤条件。
  3. 数据权限 (MyBatis-Plus):控制“你能看项目里的哪些数据行/列”。即行级权限(如:仅看本部门数据)和列级权限(如:薪资字段对普通员工不可见)。

⚙️ 二、 核心实现方案

1. 功能权限:基于 Spring Security
  • 实现方式:使用 Spring Security 的@PreAuthorize注解配合 SpEL(Spring Expression Language)。
  • 原理
    • 用户登录时,UserDetailsService从数据库加载用户的角色和权限列表(如project:admin,data:query)。
    • 在 Controller 或 Service 方法上使用注解,例如@PreAuthorize("hasAuthority('DATA_QUERY')")
    • 对于项目级别的入口控制,可以结合路径变量,例如@PreAuthorize("#projectId == authentication.projectId")来校验用户是否有权访问该特定项目。
2. 项目权限 & 数据权限:基于 MyBatis-Plus 拦截器
  • 实现方式:利用 MyBatis-Plus 的DataPermissionInterceptor或自定义InnerInterceptor
  • 原理
    • 拦截 SQL:在 SQL 执行前(beforeQuery),拦截所有的SELECT语句。
    • 解析注解:检查 Mapper 或 Service 方法上是否有自定义的权限注解(如@DataScope)。
    • 动态拼接
      • 项目权限:根据当前登录用户上下文中的currentProjectId,自动拼接AND project_id = ?
      • 数据权限:根据用户的角色(如部门经理、普通员工),拼接不同的 WHERE 条件,例如AND dept_id IN (1,2)

⏱️ 三、 请求完整的时序交互

这是一个用户发起数据查询请求(例如:查询某项目下的销售报表)的完整时序图解:

👤 1. 认证与功能鉴权阶段
  1. 用户请求:用户携带 Token(如 JWT)访问数据中台的查询接口/api/report/sales?projectId=100
  2. JWT 过滤器JwtAuthenticationTokenFilter拦截请求,解析 Token,将用户信息(包含用户ID、角色列表、权限字符串)存入SecurityContextHolder
  3. Spring Security 鉴权
    • 框架检查该接口所需的权限(例如REPORT_VIEW)。
    • 对比当前用户拥有的权限。
    • 结果:如果用户没有功能权限,直接返回 403 Forbidden,请求结束;如果有权限,进入业务逻辑层。
🔍 2. 项目与数据权限处理阶段
  1. 业务逻辑处理:Controller 调用 Service 层方法。
  2. 注解识别:假设 Service 方法上标注了@DataScope(deptAlias = "d", projectAlias = "p")
  3. MyBatis-Plus 拦截
    • DataPermissionInterceptor拦截到即将执行的 SQL 查询。
    • 获取上下文:从 ThreadLocal 或 SecurityContext 中获取当前用户对象。
    • 生成过滤片段
      • 项目权限:检查用户是否属于项目 100,生成p.id = 100
      • 数据权限:检查用户角色(如“华东区经理”),生成d.region = 'EastChina'
  4. SQL 改写:拦截器将原始 SQL:
    SELECT * FROM sales s JOIN dept d ON s.dept_id = d.id
    动态改写为:
    SELECT * FROM sales s JOIN dept d ON s.dept_id = d.id WHERE p.id = 100 AND d.region = 'EastChina'
📊 3. 数据执行与返回
  1. 数据库执行:改写后的 SQL 发送到数据库执行。
  2. 结果返回:数据库返回过滤后的数据集给用户。

📊 四、 权限类型与技术实现对照表

权限类型控制粒度核心技术实现机制典型场景
功能权限菜单/按钮/APISpring Security@PreAuthorize注解 + 角色权限匹配普通用户看不到“系统管理”菜单
项目权限项目/工作空间MyBatis-Plus 拦截器SQL 拦截 +project_id自动注入用户 A 只能看到项目 A 的数据,看不到项目 B
数据权限数据行/列MyBatis-Plus 拦截器SQL 拦截 + 动态 WHERE 条件拼接销售员只能看自己的订单,经理看全组订单

💡 五、 关键代码逻辑示意

1. MyBatis-Plus 拦截器核心逻辑

// 实现 InnerInterceptor 接口 public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { // 1. 获取当前用户信息 LoginUser user = SecurityUtils.getLoginUser(); // 2. 判断是否需要数据权限(排除管理员) if (user.isAdmin()) return; // 3. 获取注解配置的表别名 String deptAlias = getDataScopeAlias(ms, "dept"); String projectAlias = getDataScopeAlias(ms, "project"); // 4. 拼接 SQL 片段 StringBuilder sqlFilter = new StringBuilder(); // 项目权限:限制只能看自己加入的项目 sqlFilter.append(projectAlias).append(".id IN (").append(user.getProjectIds()).append(") "); // 数据权限:根据角色限制数据范围 (例如:仅本人、本部门) if ("dept".equals(user.getRole().getDataScopeType())) { sqlFilter.append(" OR ").append(deptAlias).append(".id = ").append(user.getDeptId()); } // 5. 将拼接好的 SQL 条件注入到查询参数中 // MyBatis-Plus 会自动将这个条件合并到原生 SQL 的 WHERE 后面 injectFilterToParameter(parameter, sqlFilter.toString()); }

2. Service 层使用注解

@Service public class ReportService { // dataScope 注解指定了部门表别名和项目表别名 @DataScope(deptAlias = "d", projectAlias = "p") public List<SalesReport> getReports(Long projectId) { // 这里写正常的业务查询,无需手动写 project_id 和 dept_id 的过滤 // 拦截器会自动帮你加上 return salesMapper.selectReports(projectId); } }

📌 六、 总结建议

这套方案的优势在于解耦透明

  1. 开发友好:业务开发人员在写 Mapper 时,只需要关注业务逻辑 SQL,不需要在每个 SQL 里都手写WHERE project_id = ?,由拦截器统一处理。
  2. 安全统一:Spring Security 负责大门(功能)的钥匙,MyBatis-Plus 负责数据库(数据)的过滤网,两者结合能有效防止越权访问。

在实际落地时,先搭建好用户-角色-权限的管理后台,确保管理员可以灵活配置某个角色是“本部门数据”还是“全部数据”,并将这些配置存储在数据库中,供拦截器读取。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/19 13:30:58

Langchain-Chatchat与Neo4j图数据库结合:挖掘知识间深层关系

Langchain-Chatchat与Neo4j图数据库结合&#xff1a;挖掘知识间深层关系 在企业知识管理日益复杂的今天&#xff0c;一个普遍存在的痛点是&#xff1a;我们拥有海量文档&#xff0c;却难以从中快速获取真正有用的信息。传统的搜索方式依赖关键词匹配&#xff0c;结果常常是“找…

作者头像 李华
网站建设 2026/4/13 8:41:21

自抗扰控制(ADRC)这玩意儿玩起来挺有意思的。今天咱们就拆开它的内核看看,特别是怎么从传递函数推导到PID等效。先来段MATLAB代码热热身

自抗扰控制&#xff0c;幅频特性曲线&#xff0c;传函推导&#xff0c;pid等效&#xff0c;跟踪曲线&#xff0c;抗扰曲线。 s tf(s); G 1/(s^2 2*0.6*5*s 5^2); % 二阶振荡环节 bode(G), grid on 这代码画出来的幅频特性曲线能直观展示系统谐振峰的位置。注意看相位曲线…

作者头像 李华
网站建设 2026/4/22 6:36:02

单片机 433MHz 超再生模块发送接收 Proteus 仿真探秘

单片机433MHz超再生模块发送接收Proteus仿真源程序 使用Proteus7.8&#xff0c;实现超再生模块接收发送程序的仿真。 附有原理说明和单片机程序下载。 就是这种433M超再生收发模块&#xff1a;在电子制作的世界里&#xff0c;433MHz 超再生模块因其成本低、易实现等特点&#x…

作者头像 李华
网站建设 2026/4/16 17:02:42

基于改进A*算法的机器人路径规划MATLAB仿真:探索优化之路

6.基于改进A*算法的机器人路径规划MATLAB仿真程序&#xff08;含注释) 改进方法: 1、8个搜索方向变5个 2、冗余节点的删除 3、对评价函数f(n)进行改进 代码拿来可以直接用。在机器人路径规划领域&#xff0c;A算法一直是经典且应用广泛的方法。不过&#xff0c;为了让算法更加高…

作者头像 李华
网站建设 2026/4/23 1:54:01

单电阻采集FOC在STM32 F1/F3芯片上的实现

提供单电阻采集Foc&#xff0c;stm32 f1/f3芯片由于是源码不换在电机控制领域&#xff0c;磁场定向控制&#xff08;FOC&#xff09;技术因其能够实现高精度、高性能的电机控制而备受青睐。而单电阻采集方案则以其成本低、硬件设计简单的优势&#xff0c;在实际应用中有着广泛的…

作者头像 李华
网站建设 2026/4/18 6:30:06

探索四旋翼无人机的ADRC轨迹跟踪算法

四旋翼无人机自抗扰控制算法研究 ADRC 轨迹跟踪 附带说明文在无人机的控制领域&#xff0c;实现精准的轨迹跟踪一直是个热门话题。今天咱们就唠唠四旋翼无人机的自抗扰控制算法&#xff08;ADRC&#xff09;在轨迹跟踪方面的神奇之处。 什么是自抗扰控制算法&#xff08;ADRC&a…

作者头像 李华