 Java 權(quán)限體系 第一篇:從 ACL 到 RBAC、ABAC、ReBAC——權(quán)限模型到底在解決什么問題)
玩轉(zhuǎn) Java 權(quán)限體系 第一篇從 ACL 到 RBAC、ABAC、ReBAC——權(quán)限模型到底在解決什么問題Java 圈里聊權(quán)限開口基本都是 Spring Security、Shiro、Sa-Token。但這三個(gè)東西解決的是同一層問題嗎其實(shí)不是。它們更像執(zhí)行器而真正決定你系統(tǒng)會(huì)不會(huì)越權(quán)、能不能審計(jì)、要不要重寫一遍的是它們背后那套訪問控制模型。筆者的第一個(gè)真實(shí)教訓(xùn)來(lái)得很早某天產(chǎn)品加了一句部門經(jīng)理也能看本部門的數(shù)據(jù)于是PreAuthorize(hasRole(MANAGER))后面開始長(zhǎng)出一堆if (deptId user.deptId)半年后沒人說得清哪個(gè)接口是完整的權(quán)限判斷。這就是典型的模型沒選對(duì)框架只能拿來(lái)打補(bǔ)丁。這一篇不談代碼怎么寫只把 ACL / DAC / MAC / RBAC / ABAC / ReBAC 這條演進(jìn)線講清楚每個(gè)模型的判定式是什么、它在什么場(chǎng)景會(huì)撐不住、以及這些模型在 Java 生態(tài)里分別落在哪一層。文末會(huì)給出筆者自己的選型判斷。1. 先把三個(gè)詞分開認(rèn)證、授權(quán)、訪問控制模型混用這三個(gè)詞是絕大多數(shù)權(quán)限討論吵不起來(lái)的原因。NIST 在 SP 800-162 里劃得很干凈認(rèn)證是驗(yàn)證主體確實(shí)被授權(quán)使用它拿出來(lái)的那個(gè)標(biāo)識(shí)而授權(quán)是對(duì)一次具體請(qǐng)求作出允許或拒絕的決定兩者不是一回事。原文說得很直白——認(rèn)證不等于訪問控制或授權(quán)。來(lái)源認(rèn)證 Authentication → 你是誰(shuí)登錄、token、Passkey、mTLS 授權(quán) Authorization → 這一次請(qǐng)求能不能放行permit / deny 訪問控制模型 AC Model → 能不能這件事用什么數(shù)據(jù)結(jié)構(gòu)去表達(dá)和推理簡(jiǎn)單理解模型是數(shù)據(jù)模型的選型框架是這套判定式的執(zhí)行位置。Spring Security 的過濾器鏈、Shiro 的Subject、Sa-Token 的StpUtil都是執(zhí)行位置它們并不強(qiáng)制你用哪種模型。順著這個(gè)劃分SP 800-162 還給出了一組后來(lái)被整個(gè)行業(yè)包括零信任標(biāo)準(zhǔn)沿用的角色詞組件全稱干什么PEPPolicy Enforcement Point攔截請(qǐng)求、執(zhí)行 PDP 的結(jié)論P(yáng)DPPolicy Decision Point計(jì)算決策“評(píng)估適用的策略并給出結(jié)論”PIPPolicy Information Point提供決策所需的屬性數(shù)據(jù)PAPPolicy Administration Point寫策略、測(cè)策略、調(diào)策略的后臺(tái)Context Handler—把上面幾方的調(diào)用順序編排起來(lái)來(lái)源這套詞很重要因?yàn)榈谒?、第五篇里所有網(wǎng)關(guān)鑒權(quán)“授權(quán)中臺(tái)”把策略搬出應(yīng)用的討論本質(zhì)都是在問同一件事你的 PEP 和 PDP 分別坐在哪里。2. 演進(jìn)線從文件誰(shuí)能讀寫到每次請(qǐng)求重新判斷這條線不是編年史堆料每一步都在補(bǔ)上一步的表達(dá)能力缺口。1960s–70s 1992 / 1996 2004 / 2013 2013 / 2014 2019 2020 DAC · MAC → RBAC 模型 → ANSI INCITS 359 → XACML 3.0 → Zanzibar → 零信任 NIST DoD 場(chǎng)景 角色做中間層 2004 批準(zhǔn) 屬性四分類 關(guān)系元組 SP 800-207 術(shù)語(yǔ)出自 權(quán)限掛角色 2012 修訂 userset 規(guī)則 2020-08 TCSEC SP 800-162 ABAC2014-01幾個(gè)關(guān)鍵錨點(diǎn)都能核對(duì)時(shí)間事件出處1960s–1970sDAC / MAC 概念出現(xiàn)在美國(guó)國(guó)防部應(yīng)用術(shù)語(yǔ)在 TCSEC“Orange Book”中被定義NIST SP 800-1621973機(jī)密性模型 Bell-LaPadula 的原始載體是 MITRE 技術(shù)報(bào)告 MTR-2547其 Volume II 于 1996 年被期刊重刊DOI1975 / 1977Biba 完整性模型年份存在分歧工程文檔常寫 1975學(xué)術(shù)引用多為 1977 的 MITRE 報(bào)告原始報(bào)告本次未取到Casbin 文檔1992NIST 提出通用 RBAC 模型三條規(guī)則角色指派、角色授權(quán)、事務(wù)授權(quán)核心特征是所有訪問都經(jīng)由角色NIST RBAC FAQ1996RBAC 四層級(jí)模型RBAC0–RBAC3經(jīng)典論文IEEE Computer29(2): 38-47DOI2004-02-11NIST RBAC 模型成為美國(guó)國(guó)家標(biāo)準(zhǔn)ANSI/INCITS 359-2004NIST 項(xiàng)目頁(yè)2012-05-29該標(biāo)準(zhǔn)修訂為INCITS 359-2012同上2013-01-22XACML 3.0成為 OASIS Standard2.0 是 2005-02-011.0 是 2003-02-18OASIS2014-01NIST SP 800-162《ABAC 定義與考量》發(fā)布Final——注意中文資料里的2018 年多為轉(zhuǎn)載時(shí)間NIST2019GoogleZanzibar論文USENIX ATC 19標(biāo)題為Google’s Consistent, Global Authorization SystemUSENIX PDF2020-08NIST SP 800-207《Zero Trust Architecture》發(fā)布NIST這里有個(gè)容易被忽略但很有說服力的Java 本地注腳JVM 自己就有一套代碼級(jí)授權(quán)java.security.Policy/ Security Manager從 Java 1.0 就在而它正在被官方拆除——JEP 411Status: Closed/DeliveredRelease 17把它標(biāo)記為待移除JEP 486Release 24永久禁用它。JEP 411 的原話相當(dāng)直白它多年來(lái)不是保護(hù)客戶端 Java 代碼的主要手段也很少被用于服務(wù)端維護(hù)成本卻很高并且官方明確不提供替代品。JVM 內(nèi)置授權(quán)Policy / Security Manager → 退場(chǎng)Java 17 棄用Java 24 永久禁用 Java 側(cè)權(quán)限模型剩下的三條落點(diǎn)應(yīng)用框架Spring Security / Shiro / Sa-Token 容器規(guī)范Jakarta Authorization即 JACC 外置授權(quán)服務(wù)Casbin / OpenFGA / Cerbos / Keycloak注JEP 編號(hào)、日期與狀態(tài)均為 OpenJDK 官方頁(yè)面可核對(duì)的事實(shí)“最終收斂到三條路是筆者歸納不是官方表述。JACC 的定位是為授權(quán)模塊定義一個(gè)低層 SPI讓容器把授權(quán)決策外包給策略模塊”這一點(diǎn)與 PEP/PDP 分離是同一個(gè)思想。來(lái)源3. 五個(gè)模型的判定式一張表看懂差異把每個(gè)模型壓縮成一行判定式差異立刻就出來(lái)了。模型判定式本文歸納非原文公式權(quán)限存在哪撐不住的場(chǎng)景DACdecide(subject, object, ACL[object] ∪ 屬主自由裁量)對(duì)象上屬主可改對(duì)象海量時(shí)無(wú)法治理誰(shuí)能改 ACL本身沒人管MACpermit ? 對(duì)象密級(jí)標(biāo)簽被主體許可級(jí)別覆蓋用戶不能改標(biāo)簽label業(yè)務(wù)系統(tǒng)沒有密級(jí)這種東西變更要走中央授權(quán)RBACpermit ? ?r ∈ 會(huì)話中激活的角色 : (r, op, obj) ∈ PAuser→role→permission 三張關(guān)系表約束涉及對(duì)象屬性/時(shí)間/位置時(shí)只能把約束編進(jìn)角色 → 角色爆炸ABACpermit/deny ? policy(attrs(subject), attrs(object), attrs(action), attrs(environment))策略布爾規(guī)則集決策前無(wú)法回答誰(shuí)能看這條數(shù)據(jù)審計(jì)昂貴ReBACCheck(user#relationobject)由關(guān)系元組 userset 重寫規(guī)則展開關(guān)系元組圖屬性類條件需額外機(jī)制可讀性依賴圖遍歷與緩存Q1ACL 和 RBAC 到底差在哪一步差在中間層。ACL 把誰(shuí)能對(duì)這個(gè)對(duì)象干什么直接寫在對(duì)象上Windows 文件權(quán)限、Linux 的 owner/group/other、PostgreSQL 的GRANT、K8s 的 RoleBinding 都是這一族。它的致命問題不是不安全而是沒法批量管理一百萬(wàn)條文檔各自帶一張 ACL你無(wú)法回答這個(gè)新員工多了哪些權(quán)限。RBAC 的關(guān)鍵設(shè)計(jì)是引入角色作為唯一的授權(quán)通道。NIST FAQ 里那句a key feature of this model is that all access is through roles就是這個(gè)意思——權(quán)限不許直接掛到用戶身上。來(lái)源順帶把常被混用的兩個(gè)詞分清用戶組是用戶的集合角色是權(quán)限的集合組不攜帶權(quán)限角色攜帶。RBAC 的標(biāo)準(zhǔn)結(jié)構(gòu)里還有會(huì)話中激活角色的子集這一層Core RBAC 明確包含 role activation這也是 RBAC 比權(quán)限集合打平多出來(lái)的能力。NIST RBAC 參考模型由四個(gè)組件構(gòu)成前兩個(gè)是主體后兩個(gè)才是約束組件管什么Core RBAC最小元素集與關(guān)系用戶-角色指派、權(quán)限-角色指派、會(huì)話內(nèi)角色激活。標(biāo)準(zhǔn)明確Core 在任何 RBAC 系統(tǒng)里都是必需的其余組件互相獨(dú)立Hierarchical RBAC角色繼承引入角色的授權(quán)用戶集 / 授權(quán)權(quán)限集Static SoD靜態(tài)職責(zé)分離約束用戶到角色的指派比如同一人不能同時(shí)擁有出納和會(huì)計(jì)Dynamic SoD動(dòng)態(tài)職責(zé)分離約束同一次會(huì)話里被激活的角色可以同時(shí)擁有但不能同時(shí)啟用來(lái)源這張表后面會(huì)用到標(biāo)準(zhǔn)里的約束只有 SoD 這兩種它們只管角色完全不涉及對(duì)象屬性、行范圍、時(shí)間窗、審批關(guān)系。Q2ABAC 的四類屬性是哪四類先給一句最省事的對(duì)照RBAC 判定用 1 個(gè)屬性角色 → 有 NIST 標(biāo)準(zhǔn)INCITS 359 ABAC 判定用 4 類屬性主體/對(duì)象/操作/環(huán)境 → 標(biāo)準(zhǔn)載體是 SP 800-162 XACML這里必須說清一個(gè)措辭分歧否則容易被同行挑刺四類屬性的分類法其實(shí)來(lái)自 XACMLsubject / (resource) object / action / environment conditionsOASIS 規(guī)范里對(duì)應(yīng)四個(gè)屬性類別 URI而 SP 800-162 正文用的是subject / object / environment / operations(activities)。兩邊語(yǔ)義一致命名不同。來(lái)源1 來(lái)源2ABAC 的定義原文值得抄進(jìn)設(shè)計(jì)文檔主體對(duì)對(duì)象執(zhí)行操作的請(qǐng)求是否被批準(zhǔn)取決于主體被賦予的屬性、對(duì)象被賦予的屬性、環(huán)境條件以及一組以這些屬性和條件表達(dá)的策略。SP 800-162 里最有價(jià)值的一句話是它沒有把 ABAC 說成 RBAC 的替代品而是反過來(lái)定位ACL 和 RBAC 在某種意義上是 ABAC 的特例ACL 工作在身份這個(gè)屬性上RBAC 工作在角色這個(gè)屬性上。與 ABAC 的關(guān)鍵差異在于用復(fù)雜布爾規(guī)則集表達(dá)策略這個(gè)概念。來(lái)源同一節(jié)還點(diǎn)了另一處要害ACL/RBAC 也能達(dá)成 ABAC 的目標(biāo)但要證明訪問控制需求被滿足會(huì)變得困難而昂貴而且一旦需求變化很難找出所有需要跟著改的實(shí)現(xiàn)位置。這句話就是權(quán)限系統(tǒng)重構(gòu)的立項(xiàng)理由。Q3ReBAC 是不是新東西思想不新工程化是新的。ReBAC這個(gè)縮寫不是 Zanzibar 論文的用詞——論文自稱是一個(gè)存儲(chǔ)與評(píng)估訪問控制列表ACL的全球系統(tǒng)把 Zanzibar 歸納為 ReBAC 是后續(xù)開源實(shí)現(xiàn)OpenFGA、SpiceDB做的事。來(lái)源它的數(shù)據(jù)模型只有兩樣?xùn)|西一張?jiān)M和一組展開規(guī)則元組?object?#relation?user? object namespace:object-id user user-id | ?object?#relationuserset 展開this直接| computed userset同對(duì)象內(nèi)其他關(guān)系| tuple to userset沿父對(duì)象繼承 算子union / intersection / exclusion論文給的兩個(gè)數(shù)字解釋了為什么值得學(xué)擴(kuò)展到數(shù)萬(wàn)億張 ACL、每秒數(shù)百萬(wàn)次授權(quán)請(qǐng)求三年生產(chǎn)運(yùn)行中維持95 分位延遲低于 10 毫秒、可用性高于 99.999%服務(wù)對(duì)象包括 Calendar、Drive、Photos、YouTube。一致性靠zookie協(xié)議保證 ACL 更新與內(nèi)容更新之間的因果順序。來(lái)源用 DSL 寫出來(lái)是這樣OpenFGA 的語(yǔ)法viewer from parent_folder就是 tuple-to-usersetdefine viewer: [user, domain#member] or writer or viewer from parent_folder來(lái)源ReBAC 真正的獨(dú)特點(diǎn)是對(duì)象與對(duì)象之間的關(guān)系文件夾→文檔是一等公民。RBAC 的對(duì)象只是被 permission 命中繼承要靠建模ReBAC 里繼承是一次查詢。至于部門即父對(duì)象這類組織關(guān)系天然就該存成元組而不是存成角色。工業(yè)實(shí)現(xiàn)的取舍也可以核對(duì)OpenFGA 明確其 JSON 語(yǔ)法closely tracks the original Zanzibar paper 的語(yǔ)法DSL 只是編譯到 JSON 的語(yǔ)法糖CNCF 項(xiàng)目2022-09-14 入選2025-10-28 升為 Incubating來(lái)源SpiceDB 則在與 Zanzibar 的官方對(duì)照頁(yè)里承認(rèn)簡(jiǎn)化了存儲(chǔ)與一致性Zanzibar 只支持 SpannerSpiceDB 支持多種 datastorezookie 換成了更簡(jiǎn)單的讀寫一致性選項(xiàng)來(lái)源。純關(guān)系模型表達(dá)不了工作時(shí)間以外不許導(dǎo)出這類屬性條件所以兩家各補(bǔ)了一個(gè)口子SpiceDB 叫Caveats可命名、附著到關(guān)系上的布爾表達(dá)式官方稱用于建模ABAC 風(fēng)格的決策OpenFGA 叫Conditions用 Google CEL 寫表達(dá)式。來(lái)源1 來(lái)源24. 三個(gè)說法很流行但其實(shí)不準(zhǔn)確的問題這一節(jié)是筆者覺得最值得單獨(dú)拎出來(lái)的部分——它們直接決定選型討論會(huì)不會(huì)跑偏。Q1角色爆炸role explosion為什么會(huì)發(fā)生這不是坊間吐槽SP 800-162 有原話RBAC 不容易支持多因子決策例如依賴物理位置、依賴專項(xiàng)培訓(xùn)的場(chǎng)景RBAC 的角色指派往往基于較靜態(tài)的組織位置而要在這類場(chǎng)景里實(shí)現(xiàn)訪問控制決策就需要?jiǎng)?chuàng)建大量臨時(shí)性、成員極少的角色——這正是通常所說的角色爆炸。來(lái)源因果鏈?zhǔn)沁@樣的角色只能掛在用戶的靜態(tài)組織位置上 ↓ 約束一旦涉及 對(duì)象屬性 / 部門 / 時(shí)段 / 審批關(guān)系 只能把約束編碼進(jìn)角色本身 ↓ 角色數(shù)量 ≈ 角色 × 部門 × 數(shù)據(jù)范圍 × 時(shí)段 ↓ 這些 ad hoc 角色成員極少、語(yǔ)義重復(fù)、無(wú)法向?qū)徲?jì)解釋為什么有這個(gè)角色工業(yè)界兩個(gè)低成本補(bǔ)丁都在這條鏈上打洞Casbin 的RBAC with Domains給角色加一個(gè)域/租戶維度和RBAC with Conditions在規(guī)則上直接掛條件參數(shù)。來(lái)源1 來(lái)源2Q2RBAC 表達(dá)不了只看本部門數(shù)據(jù)這句話對(duì)不對(duì)過于絕對(duì)但工程語(yǔ)義上算半對(duì)。NIST FAQ 里專門有一節(jié)回應(yīng)這類批評(píng)對(duì)方舉的例子是病歷權(quán)限建立在醫(yī)生與病人的具體關(guān)系上官方回答有兩個(gè)重點(diǎn)1992 年模型本身就是only if而非if的授權(quán)語(yǔ)義——訪問只有在滿足角色要求時(shí)才授予正是這樣才允許在訪問時(shí)追加額外約束但標(biāo)準(zhǔn)沒有規(guī)定這些額外約束該怎么實(shí)現(xiàn)它的設(shè)計(jì)是讓設(shè)計(jì)者自行添加約束來(lái)處理這些關(guān)系模型本身不會(huì)妨礙你加。來(lái)源再把第 3 節(jié)那張四組件表拿出來(lái)標(biāo)準(zhǔn)層面的約束組件只有 Static SoD 和 Dynamic SoD管的全是誰(shuí)能同時(shí)/同時(shí)激活哪些角色。所以準(zhǔn)確的表述是純 RBACCore Hierarchical SoD無(wú)法簡(jiǎn)潔地表達(dá)行級(jí)/對(duì)象級(jí)約束硬要表達(dá)就要付出角色數(shù)量和維護(hù)成本的代價(jià)。中文社區(qū)那句RBAC 只能到菜單按鈕級(jí)數(shù)據(jù)權(quán)限必須靠 ABAC/ReBAC——這是工程經(jīng)驗(yàn)的概括不是任何標(biāo)準(zhǔn)的表述寫方案時(shí)可以引但不要掛 NIST 的名義。Q3ABAC 是不是就更可控了ABAC 的代價(jià)在另一個(gè)維度決策前審計(jì)。SP 800-162 §3.1.2.3 明確要求企業(yè)需要事前審計(jì)before the fact audit能力——在請(qǐng)求發(fā)生之前就知道某人對(duì)哪些對(duì)象有權(quán)限、某對(duì)象被哪些人訪問。原文緊接著寫ABAC 系統(tǒng)可能不太適合高效地進(jìn)行這類審計(jì)因?yàn)橐愠稣l(shuí)能訪問這條數(shù)據(jù)需要巨大的數(shù)據(jù)檢索與計(jì)算量甚至可能要拿企業(yè)里每一個(gè)已知主體去模擬一次訪問請(qǐng)求。來(lái)源同文檔另一處還提醒采用分布式訪問控制架構(gòu)時(shí)審計(jì)訪問決策與事件的能力會(huì)受到影響。結(jié)論句原文這句很適合放進(jìn)立項(xiàng)郵件ABAC 系統(tǒng)更復(fù)雜因此比更簡(jiǎn)單的訪問控制系統(tǒng)實(shí)現(xiàn)和維護(hù)成本更高。但同一份文檔也承認(rèn)ABAC 能實(shí)現(xiàn)既有的基于角色的策略并支持從角色化策略向更細(xì)粒度策略的遷移。NIST 自己在 RBAC 項(xiàng)目頁(yè)上對(duì) ABAC 的概括更口語(yǔ)“ABAC 是一種基于規(guī)則的訪問控制方法容易搭起來(lái)但難以管理。”5. 零信任到底改變了什么、沒改變什么很多方案書把零信任當(dāng)成權(quán)限模型的新一代其實(shí)不是。NIST SP 800-2072020-08Final的定義是一套不斷演進(jìn)的網(wǎng)絡(luò)安全范式把防御從靜態(tài)的、基于網(wǎng)絡(luò)邊界的位置轉(zhuǎn)向聚焦用戶、資產(chǎn)和資源其規(guī)范性定義是在把網(wǎng)絡(luò)視為已被攻破的前提下最小化每次請(qǐng)求執(zhí)行精確、最小權(quán)限訪問決策時(shí)的不確定性。來(lái)源七條原則里與權(quán)限框架直接相關(guān)的三條② 所有通信一律受保護(hù)與網(wǎng)絡(luò)位置無(wú)關(guān) ③ 對(duì)單個(gè)資源的訪問按每次會(huì)話授予 —— 進(jìn)了 A 資源不等于能進(jìn) B 資源 ⑥ 所有認(rèn)證與授權(quán)都是動(dòng)態(tài)的、訪問前嚴(yán)格執(zhí)行交易過程中持續(xù)監(jiān)控可能重新認(rèn)證與重新授權(quán)而且它把 PDP 又拆了一層Policy EnginePE做最終裁決“授予、拒絕或撤銷”Policy AdministratorPA執(zhí)行決策控制面與數(shù)據(jù)面分離。改變了什么維度傳統(tǒng)權(quán)限框架零信任之后信任來(lái)源網(wǎng)絡(luò)位置 / 內(nèi)網(wǎng)身份明確不因物理或網(wǎng)絡(luò)位置、不因資產(chǎn)歸屬而給隱含信任判定粒度一次登錄長(zhǎng)期可信per-session、per-request持續(xù)重評(píng)估PEP/PDP 位置應(yīng)用外圍一層攔截器往資源側(cè)搬成為獨(dú)立的、要有實(shí)時(shí)上下文和可撤銷能力的決策服務(wù)決策輸入角色角色 設(shè)備態(tài)勢(shì) 行為 環(huán)境屬性結(jié)論種類allow / denyallow / deny /revoke沒改變什么判定式本身仍是policy(attributes) → permit/deny也就是 ABAC 的語(yǔ)義PEP/PDP 這套詞匯也不是它發(fā)明的——SP 800-207 在給出 PDP/PEP 模型的段落有腳注 3明確寫著概念部分定義于 OASIS XACML 2.0。微分段也不等于零信任NIST 有意把它描述成 ZTA 的一種功能能力“這些定義仍在以某種方式相對(duì)邊界來(lái)定義自己比如微分段或微邊界”。還有一條常被忽略的適用邊界七條原則針對(duì)組織內(nèi)部或與伙伴組織協(xié)作完成的工作不適用于匿名公開或面向消費(fèi)者的業(yè)務(wù)流程。做 C 端產(chǎn)品時(shí)把 ZT 原則原樣搬過來(lái)會(huì)寫出很重的方案。一句話總結(jié)筆者觀點(diǎn)零信任是部署與信任模型不是新的訪問控制模型。它給權(quán)限框架出的真正考題是——你的授權(quán)決策必須能實(shí)時(shí)拿到上下文并且能被撤銷。6. 這些模型在 Java 生態(tài)里分別落在哪一層把前面的譜系映射到實(shí)際選型上一張表基本夠用模型Java 側(cè)的典型落點(diǎn)客觀狀態(tài)ACL / DAC文件與數(shù)據(jù)庫(kù)對(duì)象權(quán)限、Spring Security ACL 模塊對(duì)象級(jí) ACE 存 DB、Shiro 的 Wildcard Permissionsprinter:delete式通配串小眾但沒死ACL 模塊仍是官方文檔里的一章RBAC幾乎所有后臺(tái)的角色-菜單-按鈕三件套、Keycloak 的 Role/Group Policy、Casbin 的p, sub, obj, act RBAC matcher事實(shí)上的默認(rèn)起點(diǎn)ABACKeycloak Authorization ServicesRole/Group/User/Client/Time/Regex/JS 策略并對(duì)接 UMA、CerbosResource/Principal/Role/Scoped Policy Conditions Derived Roles、OPA/RegoCNCFGraduated2021-01-29、AWS Cedar策略語(yǔ)言化、可測(cè)試化ReBACOpenFGACNCF Incubating、SpiceDBZanzibar 血統(tǒng)元組存儲(chǔ)數(shù)據(jù)權(quán)限行級(jí)PostgreSQL RLS9.5 引入、Oracle VPD、SQL Server RLS2016 引入應(yīng)用層 MyBatis/JPA 攔截器DB 層兜底 應(yīng)用層拼接并存數(shù)據(jù)權(quán)限列級(jí)PostgreSQL 列級(jí)GRANT、Oracle “Grants of Privileges on Columns”原生支持但很少被應(yīng)用用上混合Casbinacl/rbac/abac/orbac/blp/biba 等一整套可運(yùn)行配置Java 是官方支持語(yǔ)言。注2026-02 已進(jìn)入 Apache 孵化器官網(wǎng) casbin.org 現(xiàn) 301 至 casbin.apache.org單庫(kù)覆蓋多模型代價(jià)是模型語(yǔ)法要自己維護(hù)兩個(gè)技術(shù)細(xì)節(jié)值得現(xiàn)在就記住第四篇會(huì)正面用到RLS 是會(huì)被繞過的。PostgreSQL 官方文檔寫明superuser 與帶BYPASSRLS屬性的角色總是繞過行級(jí)安全表 owner 默認(rèn)也繞過可用ALTER TABLE ... FORCE ROW LEVEL SECURITY讓它受約束唯一鍵/主鍵/外鍵這類引用完整性檢查總是繞過行安全。這意味著用了 RLS 就安全是錯(cuò)的——應(yīng)用賬號(hào)一旦是表 owner策略形同虛設(shè)。來(lái)源Oracle VPD 的機(jī)制是改 SQL而不是過濾結(jié)果。官方定義是創(chuàng)建控制數(shù)據(jù)庫(kù)行級(jí)與列級(jí)訪問的安全策略做法是給命中的表/視圖/同義詞上的 SQL動(dòng)態(tài)追加一個(gè) WHERE 子句實(shí)現(xiàn)入口是DBMS_RLS包配合 application contexts。來(lái)源至于策略語(yǔ)言本身的語(yǔ)義有一個(gè)容易記錯(cuò)但很關(guān)鍵的點(diǎn)Cedar 是默認(rèn)拒絕且顯式 forbid 優(yōu)先。官方規(guī)則原文是至少一條匹配策略為 Allow 且恰好零條為 Deny 時(shí)整體才是 Allow并明確兩條原則——空策略集的默認(rèn)結(jié)果是implicit deny任一策略給出 Deny顯式 Deny 總是覆蓋其它策略的 Allow。來(lái)源 同一頁(yè)還順手回答了這算 RBAC 還是 ABAC只有 scope 沒有附加條件的策略可以作為 RBAC 方案的一部分帶條件的策略可以作為 ABAC 方案的一部分。注Cerbos不在 CNCF 項(xiàng)目列表內(nèi)官方項(xiàng)目頁(yè) 404把它寫成CNCF 項(xiàng)目是常見錯(cuò)誤。7. 標(biāo)準(zhǔn)之外token 這一層現(xiàn)在走到哪了第一篇不該以代碼結(jié)尾但應(yīng)該給一條時(shí)間是否可信的核對(duì)結(jié)論。截至 2026-09-29事項(xiàng)狀態(tài)出處OAuth 2.1仍不是 RFC。當(dāng)前修訂draft-ietf-oauth-v2-1-16Last updated2026-09-02IESG 狀態(tài)僅 “I-D Exists”未進(jìn)入 Last Calldatatracker草案里已經(jīng)確定的口徑PKCE變?yōu)楸匦鐸mplicit、資源所有者密碼憑證等不再被規(guī)定redirect URI嚴(yán)格字符串匹配目標(biāo)是合并 RFC 8252 / 9700 / 瀏覽器應(yīng)用草案并移除 RFC 9700 中被認(rèn)定不安全的特性草案正文OAuth 安全 BCPRFC 9700BCP 2402025-01Updates 6749/6750/6819RFC EditorDPoPsender-constrained token 主路RFC 94492023-09。?? 不是 9440——RFC 9440 是Client-Cert HTTP Header FieldInformational解決TLS 在反向代理終結(jié)、Java 應(yīng)用拿不到客戶端證書RFC EditormTLS 綁定 access tokenRFC 87052020-02比 OAuth 2.1 時(shí)代早得多不是新事物RFC EditorJWT 形態(tài)的 access tokenRFC 90682021-10RFC EditorOIDC Core 1.0OpenID Foundation 側(cè)為Final含 errata set 2。?? OIDC 已是 ISO/IEC 標(biāo)準(zhǔn)一說本次未核實(shí)規(guī)范正文只引用 ISO/IEC 29115別在方案里寫規(guī)范這里存在一個(gè)對(duì)權(quán)限框架很鋒利的張力筆者分析非標(biāo)準(zhǔn)表述OAuth 2.1 把 sender-constrained token 留在了擴(kuò)展DPoP / mTLS而不是核心規(guī)范里因此 Java 框架默認(rèn)發(fā)出的是不綁定的 bearer token而零信任要求可撤銷、持續(xù)重評(píng)估。這兩件事不靠給框架加攔截器解決只能靠短 TTL 撤銷通道或把決策外置到 PDP。第三、第五篇會(huì)分別處理這兩條路。最后總結(jié)先選模型再選框架。Spring Security / Shiro / Sa-Token 都是執(zhí)行器它們不阻止你寫出一個(gè) ACL 系統(tǒng)也不保證你能寫出可審計(jì)的 ABAC 系統(tǒng)。RBAC 是默認(rèn)起點(diǎn)而不是終點(diǎn)。它帶來(lái)的確定性權(quán)限只經(jīng)由角色、角色只經(jīng)由指派非常有價(jià)值一旦約束涉及對(duì)象屬性和環(huán)境你要么走域/條件補(bǔ)丁要么接受角色爆炸。RBAC 表達(dá)不了數(shù)據(jù)權(quán)限這句話別原樣引用。標(biāo)準(zhǔn)的態(tài)度是允許你加約束但不告訴你怎么加——真正的問題不是不能表達(dá)是表達(dá)得不可審計(jì)。ABAC 換來(lái)的細(xì)粒度要用審計(jì)成本付。上線前先確認(rèn)你能回答誰(shuí)能看這條數(shù)據(jù)而不是只確認(rèn)這次請(qǐng)求被拒了。ReBAC 值得學(xué)的不是名字是關(guān)系是一等公民。組織樹、文件夾、共享鏈、租戶層級(jí)本來(lái)就該是數(shù)據(jù)而不是角色。零信任沒有替代任何模型。它替代的是一次登錄長(zhǎng)期可信并把問題從權(quán)限判斷放在哪變成決策能不能實(shí)時(shí)、能不能撤銷。對(duì)后端/架構(gòu)崗筆者個(gè)人更關(guān)注三件事權(quán)限點(diǎn)的唯一權(quán)威存儲(chǔ)在哪里、需求變更時(shí)改動(dòng)面能不能被枚舉、以及審計(jì)能不能在事故前而不是事故后回答誰(shuí)有權(quán)。下一篇測(cè)評(píng)篇會(huì)把鏡頭拉回到三個(gè) Java 框架本身過濾器鏈、Subject、StpUtil三種架構(gòu)到底在哪些地方不可互換。事實(shí)說明文中所有標(biāo)準(zhǔn)編號(hào)、發(fā)布日期、版本狀態(tài)與引文均在 2026-09-29 逐條核對(duì)一手來(lái)源Biba 年份1975/1977與 ABAC四類屬性措辭存在來(lái)源分歧已在正文標(biāo)注DAC 的提出年份、TCSEC 確切編號(hào)、OIDC 的 ISO/IEC 狀態(tài)未取到一手依據(jù)故正文未作斷言。帶筆者歸納/筆者觀點(diǎn)標(biāo)記的段落為分析而非標(biāo)準(zhǔn)表述。參考資料 致謝[1] NIST SP 800-162《Guide to Attribute Based Access Control (ABAC) Definition and Considerations》[2] NIST SP 800-162 發(fā)布頁(yè)2014-01, Final[3] NIST RBAC 項(xiàng)目頁(yè)標(biāo)準(zhǔn)沿革與文獻(xiàn)清單[4] NIST RBAC FAQ四組件、RBAC0-3、約束與批評(píng)回應(yīng)[5] NIST CSRC 術(shù)語(yǔ)表DAC MAC[6] NIST SP 800-207《Zero Trust Architecture》PDF2020-08[7] USENIX ATC 19Zanzibar — Google’s Consistent, Global Authorization System[8] OASIS XACML 3.0 Core Specification2013-01-22[9] Bell-LaPadula 原始報(bào)告重刊Journal of Computer Security, DOI 10.3233/JCS-1996-42-308 IEEE Computer 29(2):38-47 RBAC ModelsDOI 10.1109/2.485845[10] OpenJDK JEP 411棄用 Security Manager JEP 486永久禁用 Security Manager[11] Jakarta AuthorizationJACC規(guī)范頁(yè)[12] Spring Security 參考文檔ACL 模塊 過濾器架構(gòu)[13] Apache ShiroPermissions 與 News3.0.x 發(fā)版動(dòng)態(tài)[14] Casbin 支持模型清單 RBAC with Domains RBAC with Conditions BLP Biba PBAC OrBAC[15] OpenFGAAuthorization Concepts Configuration Language Conceptsstore/tuple/model/Condition[16] CNCF 項(xiàng)目頁(yè)OpenFGAIncubating, 2025-10-28 OPAGraduated, 2021-01-29[17] Authzed SpiceDB與 Zanzibar 的對(duì)照 Caveats[18] AWS Cedar 策略語(yǔ)言文檔 Cedar Policy Syntaximplicit deny 與 forbid 優(yōu)先[19] Cerbos 文檔首頁(yè)[20] OPA 文檔首頁(yè) Data Filtering with OPA[21] PostgreSQL 文檔Row Security Policies CREATE POLICY GRANT列級(jí)權(quán)限[22] Oracle Database 19c 安全指南Virtual Private Database[23] Microsoft SQL ServerRow-Level Security[24] IETF datatrackerOAuth 2.1 草案狀態(tài) draft-ietf-oauth-v2-1-16 正文[25] RFC 9700OAuth 安全 BCP RFC 9449DPoP RFC 9440Client-Cert 頭 RFC 8705mTLS 與證書綁定 token RFC 9068JWT 形態(tài) access token[26] OpenID Connect Core 1.0Final, errata set 2