資料權限與功能權限本質不同:功能權限控制「能否操作功能」,資料權限控制「能存取哪筆資料、哪幾個欄位」。其粒度細、動態性強、貫穿全開發週期,無法像功能權限般後期外掛。本文提出基於 SQL 攔截重寫的資料權限架構設計。
架構總覽

核心模組獨立部署,接收:原始 SQL + 當前操作人資訊 + 權限策略 → 輸出:附加權限條件的 SQL。
四大核心設計
1. SQL 外部化與擴展性
- SQL 存放於配置檔/資料庫,開發階段僅呼叫權限模組介面
- 支援欄位級控制(如普通會員隱藏敏感欄位)
- 實現程式碼低侵入,業務邏輯無感知
2. 高效 SQL 解析引擎
- 運行期解析 AST (Abstract Syntax Tree),精準注入 WHERE/HAVING/JOIN 條件
- 支援複雜子查詢、UNION、CTE 等結構
- 快取解析結果,避免重複解析開銷
3. 權限策略模型設計
核心三元組:
- 資源:業務實體(訂單、客戶、合同)
- 主體:用戶、部門、角色(具層級關係)
- 規則:條件運算式(建立人、部門樹、標籤匹配等)
規則範例:
- 僅建立人可見
- 下級部門資料上級可見(可配置遞歸)
- 非本部門僅見部分欄位(欄位白名單)
4. 效能優化策略
- 權限決策快取(Guava Cache / Redis / Memcached)
- 規則預編譯為 SQL 片段
- 非即時一致性場景採用異步刷新
- 分頁查詢優化:先權限過濾再分頁,避免全表掃描
技術實現關鍵點
- 使用 JSQLParser 或自研解析器進行 SQL 重寫
- Spring AOP 攔截 Repository/Mapper 層(注意效能影響)
- 多租戶場景下的資料隔離(Schema/Table/Row Level)
- 審計日誌記錄所有權限決策,支援合規追溯
避坑指南
- ❌ 嘗試純 AOP 實現 → SQL 解析效能不可控
- ❌ 結果集記憶體過濾 → 大數據量 OOM 風險
- ✅ SQL 編譯期靜態分析 + 運行期動態參數綁定
- ✅ 權限模組獨立服務化,gRPC/HTTP 對外提供決策 API