老開發(fā)眼里的權限設計

1 基于角色的權限設計(RBAC)

目的:判斷用戶能否操作資源
表現(xiàn):用戶心俗、角色、資源之間的連線

users-roles-resources
  • 用戶蓉驹,特指“人”城榛。真實存在的個體
  • 資源,用戶可以操作的接口态兴、菜單狠持、按鈕、文件诗茎、圖片等工坊,都是資源
  • 角色献汗,抽象的層次很高敢订。簡單的場景,“用戶組”也可以表達這個模塊的含義

但罢吃,角色很復雜的:

約束類型 釋義 舉例
自由組合 一個人可以同時擁有任意個角色 身兼多職
繼承 擁有parent node楚午,自動獲得All children roles 的權限 中國家長
互斥 互斥的角色,一個用戶只能擁有其中的一個 男尿招、女
運行時互斥 給一個用戶配置多個角色矾柜,但,運行時就谜,只能激活一個 QQ怪蔑、360
限定個數(shù) 一個角色,只能授予有限的用戶 主席
按順序演變 嬰兒丧荐、兒童缆瓣、少年...
運行時計算 判斷操作員是否資源持有者的上級

2 常見的設計方式

類別 示例
層級 論壇系統(tǒng),超級管理員虹统、普通管理員弓坞、版主等隧甚,上級擁有下級的所有權限
角色 超市管理系統(tǒng),收銀員渡冻、開票員戚扳、倉管員等,用戶之間的地位是平等的族吻,分別對應不同的應用模塊
操作 博客系統(tǒng)帽借,文章的增刪改查等操作,都是資源
流程 公文系統(tǒng)呼奢,基層科員起草-->科長審批-->辦公室校對-->局長簽發(fā)宜雀。如果公文不在當前用戶的環(huán)節(jié),即使是局長也無權修改

分析:

  • 層級和角色握础,都可以抽象為“角色”
  • 在流程中辐董,不能把“公文”看做“資源”,節(jié)點才是禀综。節(jié)點(資源)-->角色-->用戶简烘,串起來就是權限

一句話:用戶、角色定枷、資源孤澎,很靈活的權限結(jié)構

2.1 脆弱的策略

有了好的架構,不代表落地的代碼也是靈活的欠窒。
例如覆旭,判斷一個用戶是否能查看項目報表,你的代碼或許是這樣的:

代碼

如果岖妄,新增一個角色型将,似乎,整個流程都崩潰了荐虐。當然七兜,你可以加if...else

2.2 改進語義

還是上面的示例,換個方式呢福扬,你的代碼或許是這樣的:

代碼
釋義
是否允許當前用戶查看id=12345的報表腕铸?

這樣的描述,我覺得铛碑,更符合“人”的思維習慣狠裹。

2.3 總結(jié)

判斷權限的代碼,可以寫死在代碼里汽烦,也可以放到配置文件涛菠、annotation、或是抽取到"service/util"里。無所謂啦碗暗。
我呢颈将,還是建議采用“改進的語義”。只要流程確定好了言疗,配套的驗證框架晴圾,你自己也會持續(xù)改進地嘛。即便寫死在代碼里噪奄,也是進步哦死姚,畢竟很明確嘛。

推導的內(nèi)容勤篮,僅供參考都毒。你也可以得出自己的結(jié)論。我相信碰缔,就算用了框架账劲,也會有各種不舒服。既然如此金抡,從一開始瀑焦,就抱著懷疑的態(tài)度,用實踐去求證梗肝。
代碼不會騙你榛瓮。最終,不但要用對框架巫击,還要改進

3 微服務與權限

微服務的架構禀晓,前后端完全分離。那么坝锰,在這種特定場景里粹懒,權限是怎么串起來的呢?
無論何時什黑,權限崎淳,始終關心的是用戶可以操作哪些資源:

  • 推薦使用swagger2管理后臺的接口堪夭,直觀愕把、易測試
  • 推薦使用react、angular等框架自定義“組件”

3.1 后臺接口&可讀&可寫

后臺開放的接口(API)森爽,需要指定http method恨豁。比如,Create爬迟,是write橘蜜;Get,是read。

創(chuàng)建接口的時候计福,讀或?qū)懙臋嘞蘧痛_定了跌捆。所以,讀象颖、寫佩厚,是不同的接口(資源)。

接口(資源)-->角色 --> 用戶说订,于是抄瓦,權限,又串起來了陶冷。

3.2 角色

  • 管理員钙姊、子賬號,都是特殊的角色埂伦,他們都有操作后臺的權限

  • 收銀員煞额、開票員、倉管員等沾谜,都跟特定的業(yè)務有關系

在具體的場景中立镶,你需要給某些模塊命名。這時候类早,如果媚媒,你覺得不管是“用戶”還是“資源”,都不適合涩僻,不妨用“角色”的概念封裝這些模塊缭召。
下面,著重分析下“動態(tài)角色”(先這么叫吧逆日。實現(xiàn)的時候要用到算法嵌巷,我覺得有點難。所以室抽,也沒寫全)
假設搪哪,“資源”屬于currentUser,操作員operator的角色是哪個呢坪圾?

層級關系

這些“角色”晓折,都是動態(tài)的!J扌埂漓概!怎么辦呢?

  • User表設計成樹形結(jié)構
    id/pid/level病梢,分別對應id胃珍、父節(jié)點id、層級深度。于是觅彰,根節(jié)點={1,null,1}吩蔑,一級子節(jié)點={2,1,2}...
  • 訪問接口的時候,動態(tài)判斷操作員的角色
select case (level - ${operator.level}) 
  when 1 then "immediateSubordinate"
  when -1 then "immediateSuperior"
end as role
 from t_user where id = ${currentUser.id}

動態(tài)查詢operator‘s role填抬,底層是在select tree node:

  • 傳統(tǒng)的樹形結(jié)構id&pid哥纫,查詢的時候,會用到遞歸痴奏。層級越深蛀骇,效率越差。遞歸的SQL太復雜了读拆,我沒寫
  • 推薦使用lft&rgt擅憔,左右值的預排列算法。查詢的性能非常好檐晕。但暑诸,算法的優(yōu)化,沒有固定套路辟灰,得自己寫算法

文章一開始介紹了很多種角色个榕,如果你恰好遇到了,不妨自己推導下芥喇。

3.3 前端菜單

組件的屬性:id/pid/name/接口地址/參數(shù)model等西采,都是前端自己定義的。所以继控,這塊的權限械馆,要讓前端自己配置、維護武通。

  • id不要自動生成霹崎。這里的id,特指組件的id冶忱∥补剑可以借助數(shù)據(jù)庫的唯一約束,讓id是唯一的
  • 前端的代碼里囚枪,find組件by id派诬。當然,你也可以使用有意義的name眶拉,不過呢千埃,你怎么保證name不會重復呢憔儿?或者忆植,也可以使用組件的路徑(假設組件跟菜單一樣,有嚴格的層級結(jié)構)。無所謂了朝刊,反正是前端自己維護耀里。
  • 配置(前端自己配置。后端需要提供配置的表拾氓、邏輯)

    組件 --> 角色 --> 用戶

  • 權限控制的流程

    • 后端需要提供配置的表冯挎、邏輯
    • 前端自己配置所有的組件:菜單、按鈕咙鞍、鏈接房官、文件等
    • 用戶登錄后,訪問后臺的API续滋,返回配置的組件列表(tree)
    • 前端翰守,根據(jù)返回的“組件tree”,動態(tài)展示
    • 前端訪問后臺接口的時候疲酌,帶上操作員的token
    • 后端判斷“操作員”能否操作資源

3.4 總結(jié)

或許蜡峰,干聊流程,你覺得暈朗恳。來點實在的唄:

數(shù)據(jù)庫建模

相比數(shù)據(jù)庫建模湿颅,我更加推薦DDD:分析業(yè)務流程、推演各個模塊粥诫,最后油航,再考慮配置、存儲

一句話:前端“組件”的權限怀浆,由前端負責劝堪;最嚴格的權限校驗,還是要在后端做揉稚。

4 spring security實戰(zhàn)

源碼
gitHub上的代碼和文檔秒啦,結(jié)合spring security的資料,分步驟實現(xiàn)了這篇文章中的觀點搀玖。
數(shù)據(jù)庫/緩存/服務注冊與發(fā)現(xiàn)/負載均衡等余境,代碼里都沒有。因為灌诅,service mesh已經(jīng)將這些功能都挪到sidecar里了芳来,換句話說,運維自己會搞定的猜拾,開發(fā)人員不需要管

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末即舌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子挎袜,更是在濱河造成了極大的恐慌顽聂,老刑警劉巖肥惭,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異紊搪,居然都是意外死亡蜜葱,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門耀石,熙熙樓的掌柜王于貴愁眉苦臉地迎上來牵囤,“玉大人,你說我怎么就攤上這事滞伟〗伊郏” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵梆奈,是天一觀的道長汹桦。 經(jīng)常有香客問我,道長鉴裹,這世上最難降的妖魔是什么舞骆? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮径荔,結(jié)果婚禮上督禽,老公的妹妹穿的比我還像新娘。我一直安慰自己总处,他們只是感情好狈惫,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鹦马,像睡著了一般胧谈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上荸频,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天菱肖,我揣著相機與錄音,去河邊找鬼旭从。 笑死稳强,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的和悦。 我是一名探鬼主播退疫,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼鸽素!你這毒婦竟也來了褒繁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤馍忽,失蹤者是張志新(化名)和其女友劉穎棒坏,沒想到半個月后燕差,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡俊抵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年谁不,在試婚紗的時候發(fā)現(xiàn)自己被綠了坐梯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片徽诲。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖吵血,靈堂內(nèi)的尸體忽然破棺而出谎替,到底是詐尸還是另有隱情,我是刑警寧澤蹋辅,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布钱贯,位于F島的核電站,受9級特大地震影響侦另,放射性物質(zhì)發(fā)生泄漏秩命。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一褒傅、第九天 我趴在偏房一處隱蔽的房頂上張望弃锐。 院中可真熱鬧,春花似錦殿托、人聲如沸霹菊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽旋廷。三九已至,卻和暖如春礼搁,著一層夾襖步出監(jiān)牢的瞬間饶碘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工馒吴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留熊镣,地道東北人。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓募书,卻偏偏與公主長得像绪囱,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子莹捡,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345