权限即数据:企业系统中的字段级访问控制架构实战(β=0.7)
摘要
本文在 β=0.6 版本基于规则表与命中记录表(biz_rule_hit)实现字段级动态权限控制的基础上,提出 β=0.7 三层合并模型:表级默认基线、字段级固定默认、命中规则。通过内存统一计算,先以表级基线封顶字段可见度,再结合字段默认值兜底,最后由命中规则灵活提升权限等级(editable/view/masked/hidden)。该方案支持多规则叠加、对象/记录级封顶、脱敏内聚与审计钩子,兼顾性能与可维护性,适用于跨表、跨模块的统一权限治理,满足金融、医疗、SaaS 多租户等复杂场景的合规与高效需求。
关键词
字段权限、动态授权、合并策略、脱敏审计、表级基线、三层模型
目录
- 数据库设计
- 读取规则表
- 表级基线配置表
- 内存合并计算
- 流程图(β=0.7)
- 新增能力
- 返回前端
- 版本变化对比:β=0.6 → β=0.7
- 应用场景示例
- 总结
1️⃣ 数据库设计
CREATE TABLE biz_rule_hit (biz_table_name VARCHAR(128) NOT NULL,biz_id INT NOT NULL,rule_id INT NOT NULL,user_id INT NOT NULL,hit_time DATETIME DEFAULT GETDATE(),PRIMARY KEY (biz_table_name, biz_id, rule_id, user_id)
);
一张表管理所有业务表的命中记录,支持长期保存与审计。
2️⃣ 读取规则表
class Rule {int ruleId;String evaluatedCondition;List<String> editable;List<String> view;List<String> masked;List<String> hidden;String bizTable;
}
3️⃣ 表级基线配置表
CREATE TABLE table_base_policy (biz_table_name VARCHAR(128) NOT NULL,principal_type VARCHAR(32) NOT NULL,principal_id INT NOT NULL,base_level INT NOT NULL, -- 0=hidden, 1=masked, 3=editablePRIMARY KEY (biz_table_name, principal_type, principal_id)
);
4️⃣ 内存合并计算(β=0.7 核心优化)
Map<String, Integer> levelMap = Map.of("hidden", 0,"masked", 1,"view", 2,"editable", 3
);void mergePermissions(Map<Integer, Map<String, String>> bizPermissions,List<Map<String, Object>> bizData,List<Rule> rules,Map<String, Integer> levelMap,Map<String, Integer> tableBaseMap
) {for (Map<String, Object> row : bizData) {int bizId = (Integer) row.get("id");bizPermissions.putIfAbsent(bizId, new HashMap<>());Integer ruleId = (Integer) row.get("rule_id");String bizTable = (String) row.get("biz_table_name");int tableBase = tableBaseMap.getOrDefault(bizTable, 3);int fieldDefault = 2;int baseLevel = Math.min(tableBase, fieldDefault);int currentLevel = 0;if (ruleId != null) {Rule rule = rules.stream().filter(r -> r.ruleId == ruleId).findFirst().orElse(null);if (rule != null) {for (String field : allFields(rule)) {int ruleLevel = levelMap.getOrDefault(rule.getLevelForField(field), 0);int finalLevel = Math.max(Math.max(baseLevel, currentLevel), ruleLevel);bizPermissions.get(bizId).put(field, getLevelName(finalLevel, levelMap));}}} else {for (String field : row.keySet()) {bizPermissions.get(bizId).put(field, getLevelName(baseLevel, levelMap));}}}
}
5️⃣ 流程图(β=0.7)
[表级基线] → min(表基线, 字段默认=2)↓与当前已合并权限取 max↓与命中规则等级取 max↓最终字段权限
6️⃣ 新增能力
- 表级封顶
- 字段固定默认 view
- 规则提升
- 审计钩子
- 脱敏内聚
7️⃣ 返回前端
List<Map<String, Object>> result = bizData.stream().map(row -> {int bizId = (Integer) row.get("id");row.put("permissions", bizPermissions.getOrDefault(bizId, Collections.emptyMap()));return row;}).collect(Collectors.toList());
8️⃣ 版本变化对比:β=0.6 → β=0.7
对比维度 | β=0.6 流程 | β=0.7 流程 | 升级价值 |
---|---|---|---|
步骤 1 | 命中规则 | 表级基线 | 全局收口 |
步骤 2 | 合并字段权限 | min(表基线, 字段默认) | 固定默认可见 |
步骤 3 | — | 当前已合并权限 | 多规则累加 |
步骤 4 | — | max(前一结果, 命中规则) | 灵活提升 |
权限等级 | 0/1/2/3 | 同 β=0.6 | 兼容迁移 |
脱敏处理 | 分散 | 内聚 | 降低重复 |
审计策略 | 无区分 | 可写仅审计 | 满足合规 |
扩展性 | 无基线 | 可选 deny 层 | 治理增强 |
9️⃣ 应用场景示例
- 金融客服脱敏展示
- 医疗病历跨科访问
- SaaS 多租户隔离
- 内部运营临时授权
✅ 总结
β=0.7 通过三层合并模型,将表级基线、字段默认、命中规则有机结合,实现了更安全、更灵活、更可治理的字段级权限控制方案,适配多行业复杂场景。