数据权限简单设计思路

现有权限控制分类

软件开发绕不过的两道基础集成功能,认证、鉴权,前者基于登录信息识别、校验、OAuth协议的授权认证、CAS、JWT等Token单点;后者采用基于Spring-Security、RBAC模型访问控制,表现为菜单、功能api访问的权限资源关联角色载体,角色关联用户的权限控制。

数据权限控制

数据权限属于权限一种,基于sql层面的字段可见、数据范围可见,常用场景,不同管理岗位同一张表不同字段可见性不同,华中区负责人看到当前区城市数据,单一城市只能看到当前市负责数据等
思考:能否通过接口返回值过滤?(分页、sql查询效率、后处理返回效率)

服务架构流程

权限字段的注册

数据权限资源的注册,需要鉴权的服务端启动的时候将自身链接数据库的所有表,所有字段的元数据信息注册到服务端,f_datacolumn用来存储字段权限信息,唯一键标识为:项目+库+表+字段名,字段类型,字段注释等辅助信息便于赋权规则时操作,时间类型赋值时间组件筛选范围,数值、字符串、字典值均可转换可视化赋值;f_rulecolumn存储权限字段赋予的规则信息;【界面可视化操作,针对指定字段+字段逻辑操作符(and、or)+字段运算符(in范围、<>=!=值、contain包含)+字段匹配值(时间组件、数值、文本、字典值、内置变量{当前用户的机构、岗位等})】f_columnrole关联字段和角色,以至角色关联用户。
在这里插入图片描述

权限字段授权

在这里插入图片描述

权限字段鉴权

在这里插入图片描述

mybatis提供的intercept插件拦截

@Intercepts({ @Signature(method = "prepare", type = StatementHandler.class, args = { Connection.class }) })
public class FetchSqlInterceptor implements Interceptor {
	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		//逻辑代码区
		return invocation.proceed();
	}
	@Override
	public Object plugin(Object target) {
		//生成代理对象
		return Plugin.wrap(target, this);
	}
	@Override
	public void setProperties(Properties properties) {
	}
}

实现 Interceptor 接口也就是实现intercept,plugin,setProperties这三个方法,其中

intercept方法是我们拦截到对象后所进行操作的位置,也就是我们之后编写逻辑代码的位置。

plugin方法,根据参数可以看出,该方法的作用是拦截我们需要拦截到的对象。

setProperties方法,我们可以通过配置文件中进行properties配置,然后在该方法中读取到配置。

这三个方法的执行顺序: setProperties—>plugin—>intercept

@Override
	public Object intercept(Invocation invocation) throws Throwable {
		StatementHandler handler = (StatementHandler)invocation.getTarget();
		//由于mappedStatement中有我们需要的方法id,但却是protected的,所以要通过反射获取
		MetaObject statementHandler = SystemMetaObject.forObject(handler);
		MappedStatement mappedStatement = (MappedStatement) statementHandler.getValue("delegate.mappedStatement");
		//获取sql
		BoundSql boundSql = handler.getBoundSql();
		String sql = boundSql.getSql();
		//增强sql
		return invocation.proceed();
	}

实现插件接口后,添加至mybatis @Configuration、@Bean配置中

sqlSessionFactory.getConfiguration().addInterceptor(new FetchSqlInterceptor());        

原始sql:

SELECT id,name,email,age FROM t_userinfo;
  • 待鉴权客户端页面请求数据接口
  • 持久层拦截使用JSqlParser工具解析原始sql获取表名
<dependency>
   <groupId>com.github.jsqlparser</groupId>
   <artifactId>jsqlparser</artifactId>
   <version>4.0</version>
</dependency>
  • 拦截调用服务端接口获取该用户拥有当前系统的字段规则(服务端根据用户code获取角色、角色关联的表字段、表字段关联的字段,根据字段规则:逻辑符+字段名+运算符+条件值,example:and age < 35),解析出字段规则表达式
  • JSqlParser工具解析原始sql对应表的where条件+and 1=1 + 字段规则表达式
  • 执行增强sql,返回数据

加强后的sql:

SELECT id,name,email,age FROM t_userinfo WHERE 1=1 and age < 35;

前端界面适配

动态渲染数据字段

根据数据鉴权返回的结果,数据范围上的限制,无需更改,字段限制上,动态适配渲染表单列即可。

开发注意事项及思考

权限合并

权限的叠加

用户和角色的关联关系是一对多的,任何如岗位上的不同权限,多部门分管的特殊情况,都可以使用多个角色分配、权限叠加使用,如此便涉及到多个角色的权限叠加结果问题,若是不同字段取多个角色关联的多个字段直接并集即可,不同角色包含同一个字段冲突导致的不同配置规则是需要逻辑层面的处理取得更大范围的逻辑上的权限为最终结果。

规则的叠加

  1. 针对多个角色叠加,导致的一个字段有多个规则是需要业务考虑的,简单的运算符上的age > 10 和 age > 25,最终取得规则一定是数据范围更大的 age > 10,<、=、!=逻辑一致;
  2. 字典值和内置变量,有逻辑上的范围大小,如当前所在的部门、上级部门、当前所处的岗位、上级领导岗位,则需梳理出字典值和内置变量中的排序字段,数值越小岗位或部门越大,根据此排序字段来合并规则条件,范围大者替代原则
  3. 若有字段配置冲突既等于又不等于,或大于大的数值小于小的数值,在角色分配叠加时候校验给出提醒是否是正确的权限需求分配方式,或冲突字段直接采用or逻辑符连接均保留(and (age > 25 or age < 10))

SQL拦截的通用可能性

  1. 基于Spring容器托管的持久层框架均可通过代理模式,截取执行的sql,例如本文的mybatis提供的插件实现(JPA中Hibernate也提供了类似StatementInspector接口类
  2. 不同类型数据库驱动如mysql提供了一个接口实现类com.mysql.jdbc.StatementInterceptor(StatementInterceptorV2)配置链接url添加参数jdbc.url=jdbc:mysql://127.0.0.1:3306/test?statementInterceptors=xxxStatementInterceptor,除此之外原生jdbc等不同封装的持久层框架可能不容易获取到sql
### Linux 权限管理的设计理念 Linux 系统中的权限管理体系旨在保障系统的安全性与稳定性,同时提供灵活的访问控制能力。该体系主要依赖于用户身份识别、文件权限设置以及特殊权限位来实现细粒度的访问控制。 #### 用户分类与角色定义 操作系统内部分为三类基本实体:用户(user),组(group),以及其他(others)[^1]。每一类都对应着不同的权限级别: - **用户 (User)**: 文件拥有者的特定权限。 - **组 (Group)**: 同一工作组内的其他成员所享有的权限。 - **其他 (Others)**: 所有不属于上述两类用户的剩余人员所能获得的操作许可。 这种划分允许管理员针对不同群体设定差异化的存取策略,从而更好地保护敏感资源并促进协作效率提升。 #### 特殊权限位的应用场景 除了常规读写执行(rwx)外,还存在一些特殊的权限标记用于满足更复杂的业务需求: - **SetUID(SUID)/SetGID(SGID)** : 当程序被执行时赋予其运行者临时性的所有者或所属群组的身份特权[^2]; ```bash chmod u+s program_name # 设置SUID位 ``` - **Sticky Bit**: 主要应用于共享目录下防止他人删除非本人创建的内容对象; ```bash chmod +t directory_path # 添加粘滞位到指定路径下的文件夹上 ``` 这些特性共同构成了一个强大而精细的安全框架,在不影响用户体验的前提下增强了数据保密性和完整性。 ### 实现机制详解 为了有效地管理和分配权限,Linux采用了多种技术手段相结合的方式: #### 访问控制列表(ACL) 传统的 Unix 风格 rwx 模型虽然简单直观但却缺乏足够的灵活性去处理复杂的企业级应用场景。因此引入了 ACLs —— Access Control Lists 的概念作为补充方案之一。它能够在不改变原有结构的基础上增加额外层次上的授权规则描述,支持更为细致入微的权利配置选项。 ```bash setfacl -m u:johndoe:r /path/to/file # 给johndoe用户授予只读权限 getfacl /path/to/file # 查看当前文件的所有ACL条目 ``` #### Role-Based Access Control (RBAC) 基于角色的访问控制系统 RBAC 是一种广泛应用于现代企业环境当中的高级安全管理方法论。通过预先定义好的职位模板关联起一系列预设动作集合作为参照标准,进而简化实际部署过程中的维护工作量并减少人为失误风险。例如在一个典型的 IT 开发团队里,设计师组长自动继承自普通设计师的基础功能之外还能行使某些专属审批权能等附加职责。 #### SSH 密钥认证机制 对于跨网络节点间的交互操作而言,则更多地依靠SSH所提供的加密通信渠道完成身份验证流程。具体来说就是利用非对称算法生成一对相互匹配却又彼此独立存在的密钥对儿——公钥公开分发给远端服务器保存备案以便后续校验之需; 私钥则由请求发起方妥善保管仅作解码用途而不应随意泄露出去以防被恶意窃取滥用造成安全隐患[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值