权限即数据:企业系统中的字段级访问控制架构实战(β=0.8)

发布于:2025-09-12 ⋅ 阅读:(23) ⋅ 点赞:(0)

摘要

β=0.8 在 β=0.7 的“三层合并模型”之上,取消命中表,将规则下推为 SQL CASE,在查询阶段直接返回命中规则的内存下标串;应用层继续执行表级基线与字段默认的合并、脱敏与审计,并新增稳定排序与 keyset 策略,系统性解决分页漂移与统计不一致。本文同时集成 β=0.7 的“极限规则应用”代码路径(封顶/兜底/deny)以保持治理能力的一致性与可回滚性。


关键字

  • 字段级权限控制
  • 表级基线封顶
  • 规则下推SQL化
  • 动态SQL CASE命中
  • 权限感知与Keyset分页
  • 脱敏与可写审计

β=0.7 基线与极限规则回顾

  • **表级基线封顶:**按主体维度配置表级上限,限制字段最大可达权限。
  • **字段固定默认:**无命中时的字段默认等级,形成“下限兜底”。
  • **规则提升叠加:**多规则命中按字段取最大提升。
  • **极限规则应用:**以“最小-最大”模型收敛,先合并默认与提升,再施加全局封顶与可选 deny,将结果拉回“安全边界”。
  • **处理顺序:**表级封顶 → 字段默认 → 规则提升 → 再封顶 → deny → 脱敏 → 审计。

命中识别前移与分页一致性(β=0.8)

  • **规则内存化与编号:**规则加载入内存稳定编号 0…N−1,每条含“SQL 条件片段 + 字段→等级映射”。
  • **SQL CASE 下推:**一次查询返回业务行与命中规则下标串,如 “0,2,”。
  • **权限感知分页:**同一条 SQL 内完成 WHERE/ORDER BY/LIMIT(或 keyset),不在页内做行级再过滤,避免漂移;必要统计用窗口函数或并行 COUNT。
  • **跨库与实时性:**无命中表,降低跨库耦合;规则更新即刻生效。
  • 以上在 β=0.7 的思路基础上将“命中识别”侧移数据库,保留合并与审计策略不变。

核心 SQL 示例(可跨方言适配)

  • MySQL:
SELECT 
  b.*,
  CONCAT(
    CASE WHEN amount > 1000 AND status = 'A' THEN '0,' ELSE '' END,
    CASE WHEN region = 'CN' THEN '1,' ELSE '' END,
    CASE WHEN vip = 1 THEN '2,' ELSE '' END
  ) AS hit_rule_indexes
FROM biz_table b
WHERE /* 业务条件 */
ORDER BY created_at DESC, id DESC
LIMIT :limit OFFSET :offset;
  • PostgreSQL/Oracle(使用 ||):
SELECT 
  b.*,
  (CASE WHEN amount > 1000 AND status = 'A' THEN '0,' ELSE '' END ||
   CASE WHEN region = 'CN' THEN '1,' ELSE '' END ||
   CASE WHEN vip = 1 THEN '2,' ELSE '' END) AS hit_rule_indexes
FROM biz_table b
WHERE /* 业务条件 */
ORDER BY created_at DESC, id DESC
OFFSET :offset ROWS FETCH NEXT :limit ROWS ONLY;
  • SQL Server(CONCAT 或 +):
SELECT 
  b.*,
  CONCAT(
    CASE WHEN amount > 1000 AND status = 'A' THEN '0,' ELSE '' END,
    CASE WHEN region = 'CN' THEN '1,' ELSE '' END,
    CASE WHEN vip = 1 THEN '2,' ELSE '' END
  ) AS hit_rule_indexes,
  COUNT(*) OVER() AS total_count
FROM biz_table b
WHERE /* 业务条件 */
ORDER BY created_at DESC, id DESC
OFFSET @offset ROWS FETCH NEXT @limit ROWS ONLY;

以上“表级基线、字段默认、规则叠加、封顶与审计”的方法论延续自 β=0.7 的合并模型。


合并引擎(集成 β=0.7 极限规则应用)

说明:以下合并引擎同时支持 β=0.8 的“命中下标串”与 β=0.7 的“单条命中或多条命中列表”,并显式实现“极限规则应用”(全局封顶 cap、字段兜底 floor 与 deny 覆盖),确保在任何命中组合下结果稳定落入安全区间。

// 等级顺序映射:hidden=0, masked=1, view=2, editable=3(示例)
static final Map<String, Integer> LEVEL = Map.of(
    "hidden", 0, "masked", 1, "view", 2, "editable", 3
);
static String levelName(int v) {
    for (var e : LEVEL.entrySet()) if (e.getValue() == v) return e.getKey();
    return "hidden";
}

// 规则定义(每条规则提供“字段 -> 目标等级”映射)
class Rule {
    int index;                      // 内存编号(0..N-1)
    Map<String, String> fieldLv;    // 字段 -> 等级名
    Map<String, Integer> fieldMax;  // 可选:字段局部封顶(极限规则)
    Map<String, Integer> fieldMin;  // 可选:字段局部兜底(极限规则)
    // ... 其它元数据(如命中条件 SQL 片段、租户范围等)
}

// 合并上下文(来自 β=0.7 的“三层合并模型”,并加入极限规则位)
class MergeContext {
    int tableCap;                       // 表级封顶(上限)
    Map<String, Integer> fieldDefault;  // 字段默认(下限)
    Map<String, Integer> denyCap;       // 可选:字段级 deny 上限(更严)
    Map<Integer, Rule> ruleIndexMap;    // 规则编号 -> 规则
}

// 解析命中下标串("0,2," -> [0,2])
static Set<Integer> parseHits(String s) {
    if (s == null || s.isEmpty()) return Set.of();
    String t = s.endsWith(",") ? s.substring(0, s.length() - 1) : s;
    if (t.isEmpty()) return Set.of();
    Set<Integer> out = new LinkedHashSet<>();
    for (String p : t.split(",")) if (!p.isBlank()) out.add(Integer.parseInt(p));
    return out;
}

// 极限规则合并:floor(兜底) -> 提升max -> 局部min/max -> 全局cap -> deny
static Map<String, String> mergeRowPermissions(
        Map<String, Object> row,
        String hitRuleIndexes,           // β=0.8 来源(命中下标串)
        List<Integer> hitRuleList07,     // β=0.7 兼容:命中ID列表(可空)
        MergeContext ctx,
        Set<String> allFields
) {
    Set<Integer> hits = new LinkedHashSet<>();
    hits.addAll(parseHits(hitRuleIndexes));
    if (hitRuleList07 != null) hits.addAll(hitRuleList07); // 兼容 β=0.7

    Map<String, Integer> result = new HashMap<>();
    for (String f : allFields) {
        // 1) 字段默认(下限)
        int v = Math.min(ctx.tableCap, ctx.fieldDefault.getOrDefault(f, LEVEL.get("hidden")));

        // 2) 规则提升(多规则取最大)
        for (int idx : hits) {
            Rule r = ctx.ruleIndexMap.get(idx);
            if (r == null) continue;
            String lvName = r.fieldLv.get(f);
            if (lvName != null) v = Math.max(v, LEVEL.getOrDefault(lvName, v));
        }

        // 3) 局部极限(每条规则可定义字段局部 min/max,逐条收敛)
        int localMin = Integer.MIN_VALUE, localMax = Integer.MAX_VALUE;
        for (int idx : hits) {
            Rule r = ctx.ruleIndexMap.get(idx);
            if (r == null) continue;
            if (r.fieldMin != null && r.fieldMin.containsKey(f))
                localMin = Math.max(localMin, r.fieldMin.get(f));
            if (r.fieldMax != null && r.fieldMax.containsKey(f))
                localMax = Math.min(localMax, r.fieldMax.get(f));
        }
        if (localMin != Integer.MIN_VALUE) v = Math.max(v, localMin);
        if (localMax != Integer.MAX_VALUE) v = Math.min(v, localMax);

        // 4) 全局封顶(表级 cap)
        v = Math.min(v, ctx.tableCap);

        // 5) deny 覆盖(更严的上限)
        if (ctx.denyCap != null && ctx.denyCap.containsKey(f))
            v = Math.min(v, ctx.denyCap.get(f));

        result.put(f, v);
    }

    // 6) 返回字符串等级(用于脱敏与审计)
    Map<String, String> named = new HashMap<>();
    result.forEach((k, val) -> named.put(k, levelName(val)));
    return named;
}
  • 要点说明:
    • **极限规则位:**在每条规则中允许配置字段级 fieldMin/fieldMax,实现“局部兜底/封顶”,与全局表级 cap、deny 叠加,保证任何叠加下都能收敛。
    • **双栈兼容:**既支持 β=0.8 的命中下标串,也兼容 β=0.7 的命中 ID 列表输入路径,便于灰度与回滚。
    • **顺序严格:**默认下限 → 提升 → 局部极限 → 全局封顶 → deny;顺序改变会破坏安全边界。

脱敏与审计接入点

  • **脱敏:**在字段达至少 view 时按字段策略执行掩码;masked 与 view 的策略互斥且幂等。
  • **审计:**对 editable 字段记录“用户-对象-字段-时间-上下文”访问与变更日志;保留命中下标串用于追溯。
  • **β=0.7 继承:**上述实践直接承接 β=0.7 的审计与脱敏内聚思路,无需改动域模型。

运维与灰度

  • **规则集版本化:**同版本内编号稳定;以配置中心下发 CASE 模板与规则映射。
  • **分页稳定:**固定 ORDER BY 键(如 created_at DESC, id DESC);大表使用 keyset 避免 OFFSET 大扫描。
  • **回滚双开关:**查询层(CASE 模板)与应用层(解析命中串)各自可回退到 β=0.7 路径。

结语

β=0.8 将“命中识别”前移到数据库层,以 CASE 生成命中下标串,解决跨库带来的复杂度与时延,同时通过稳定排序与 keyset 策略解决分页漂移;在应用层完整复用 β=0.7 的“三层合并模型”与“极限规则应用”代码,确保任何规则叠加都能在安全边界内收敛,达成“性能、治理、可审计”的工程平衡。

参考:β=0.7 合并模型概念、表级基线/字段默认、内存合并与审计脱敏思路等背景内容。


网站公告

今日签到

点亮在社区的每一天
去签到