摘要:權(quán)限設(shè)計的雜談這篇文章的定位,不是宣傳某個框架,僅僅之是梳理一下有關(guān)權(quán)限方面的一些想法和最近項目中的一些探索過程。而這兩者的取舍則是有設(shè)計人員決定的。數(shù)據(jù)抽象原則最小特權(quán)劃分從某個程度上來說決定了控制的對象,而數(shù)據(jù)抽象原則是是決定了操作。
權(quán)限設(shè)計的雜談
這篇文章的定位,不是宣傳某個框架,僅僅之是梳理一下有關(guān)權(quán)限方面的一些想法和最近項目中的一些探索過程。
我們主要想解決一下問題。
什么是權(quán)限,程序員理解的權(quán)限和客戶所理解的權(quán)限是不是一致的。
權(quán)限的劃分原則,權(quán)限到底是根據(jù)什么原則進行組合的。
角色是用戶與權(quán)限之間的必要的關(guān)系嗎?角色到底承接了什么作用。
如何進行合理的表設(shè)計。
安全框架。
1.什么是權(quán)限在很多與開發(fā)者也好,與客戶也好,溝通的過程中我們很多次提到了權(quán)限,但是權(quán)限具體的含義每個人理解的含義都不明確,這樣很容易造成雙方信息不對稱,有的人就只是把權(quán)限理解成某個頁面的是否可訪問,但是有的人卻理解成其他的東西。所以我們要徹底的定義一下權(quán)限是什么。
權(quán)限到底是名詞屬性還是動詞屬性,還是名詞、動詞屬性均包含,這對于權(quán)限的含義很重要。如果是名詞屬性的話,那么它應(yīng)該是有具體的指代物;如果是動詞,則應(yīng)該具有行為表示。
權(quán)限的名詞屬性:api接口、頁面、功能點。
權(quán)限的動詞屬性:可操作、不可操作。
那么我們現(xiàn)在來看,其實權(quán)限是名詞、動詞屬性,它一定是表達了兩層含義。即控制的對象、操作。
例如:權(quán)限A表示頁面A的可訪問。
例如:權(quán)限B表示頁面B可訪問且頁面內(nèi)的功能b不可使用
例如:權(quán)限C表示接口C不可調(diào)用。
例如:權(quán)限D(zhuǎn)表示頁面D可訪問,且接口D可訪問。
那么進一步的說明,權(quán)限可以表示單個控制的對象的操作集合,也可以表示多個控制的對象的操作集合。而這兩者的取舍則是有設(shè)計人員決定的。
2.權(quán)限的劃分原則一句話總結(jié)權(quán)限的含義:what(若干元素)進行how(若干操作)
我們了解了權(quán)限的具體含義之后,接下來就是用的問題,我們該如何去使用權(quán)限,如何將系統(tǒng)中的操作元素進行一個組合,這個我借鑒網(wǎng)上的一篇文章來解釋。劃分原則可以按照“最小特權(quán)原則”和“數(shù)據(jù)抽象原則”。
最小特權(quán)原則
我先舉一個反例,我把系統(tǒng)中所有的元素和操作都組合成一個權(quán)限。一個用戶擁有這個權(quán)限就相當(dāng)擁有了系統(tǒng)所有的功能,實際上這肯定是不行的,用戶在一套系統(tǒng)中一定有他不允許操作的內(nèi)容,哪怕是超級管理員也可能會有不能操作的元素,那么最大化權(quán)限則是行不通,因為不符合常理。
據(jù)此,我們就把權(quán)限再進行一個拆分,按照業(yè)務(wù)模塊進行拆分,但是這實際上也是不行的。就比如系統(tǒng)中的財務(wù)模塊,假定模塊中含有報銷頁面和申報頁面,如果按照模塊進行拆分,那么肯定有用戶同時包含了兩個互斥功能。
根據(jù)1和2,我們需要按照最小化進行權(quán)限劃分。但是這個也是值得商榷的,因為不同系統(tǒng),最小的權(quán)限劃分對于提供的功能來說,劃分的角度也是不同的。
數(shù)據(jù)抽象原則
“最小特權(quán)劃分”從某個程度上來說決定了控制的對象 ,而數(shù)據(jù)抽象原則是是決定了操作。
數(shù)據(jù)抽象從字面的意思來看,其實很難理解到底是什么意思。通常我們口頭上說最多的是CRUD增刪查改,這實際上就是數(shù)據(jù)抽象的一種,我們可以理解成元素操作許可權(quán)的意思。
但是CRUD并不是數(shù)據(jù)抽象的全部,增刪查改用于單實體,基本是沒問題的,但是在構(gòu)建關(guān)系上,其實是不夠用的,例如任免某個經(jīng)理管轄某個部門,從業(yè)務(wù)表面而言它修改了經(jīng)理的管轄范圍。但是從代碼底層構(gòu)建上來說,它屬于在經(jīng)理和部門間新增了一道關(guān)系,所以根據(jù)需求我們需要再額外的增加一類許可權(quán)“任免許可”,這一類型的擴展則需要根據(jù)系統(tǒng)實際的業(yè)務(wù)情況進行劃分。
“最小特權(quán)”和“數(shù)據(jù)抽象”分別決定了權(quán)限中控制的對象和操作,但是這里面還差了一個角度,則是現(xiàn)階段非常普遍的前后端分離的權(quán)限劃分的問題。
服務(wù)端的權(quán)限
前后端分離下的服務(wù)端,本質(zhì)而言只是提供接口的或者rpc服務(wù)等其他資源服務(wù)的服務(wù)提供方。
服務(wù)端能提供的權(quán)限的鑒權(quán)機制的對象:接口服務(wù)(api或者其他形式的服務(wù))不包含前端的頁面或頁面中的功能點。
前端或移動端的頁面元素的控制和鑒權(quán)實質(zhì)上不由服務(wù)端控制。
服務(wù)端可以多帶帶的控制服務(wù)的權(quán)限。
服務(wù)端的服務(wù)對象是前端、移動端、第三方客戶端,提供的服務(wù)是接口服務(wù)。
在前后端已經(jīng)分離的情況下,服務(wù)端對于前端而言只是接口的提供者,但無權(quán)干涉前端頁面的展示,服務(wù)端對于前端而言,能提供的是僅鑒權(quán)服務(wù)的接口而已,但是頁面的構(gòu)成,頁面的欄目菜單或頁面內(nèi)的功能點的構(gòu)成均由前端多帶帶完成的。
前端或移動端的權(quán)限
前端的鑒權(quán)包含頁面的可訪問,和頁面上的某項功能按鈕是否可以操作。
前端和移動端的服務(wù)對象是用戶,提供的服務(wù)是可視化的頁面。
前后端的服務(wù)對象的責(zé)任劃分清晰之后,我們就不會混雜權(quán)限的歸屬的問題,在過去前后端沒分離的情況下,頁面本身就是服務(wù)端的一體,就沒有這方面的問題。雖然分清楚了各端本質(zhì)提供的服務(wù)的情況,但是前后端分離的權(quán)限劃分中仍有新的問題。
因為服務(wù)端和前端的鑒權(quán)對象不一致,服務(wù)端只能鑒權(quán)到api接口,那么是否將api接口和前端的頁面乃至頁面功能點進行數(shù)據(jù)庫表與表層面的綁定關(guān)系。
如果進行了進行了表與表之間的綁定關(guān)系,那么整個權(quán)限系統(tǒng)的維護量,是否能在能承受范圍之內(nèi)。
如果不進行表與表之間的綁定關(guān)系,前端頁面在操作功能的時候,服務(wù)端如何鑒權(quán)頁面調(diào)用的api接口是否在用戶可操作的權(quán)限之內(nèi)?
其實上面的問題則需要一個取舍,要么增加運維成本嚴(yán)格控制前端調(diào)用api接口的關(guān)系,偏重服務(wù)端的接口服務(wù)鑒權(quán)。要么是給api接口和前端頁面及功能點再提供一個通性的邏輯判斷處理,如:頁面及調(diào)用的功能點屬于某個業(yè)務(wù)模塊的操作許可,而頁面觸發(fā)的接口也剛好是這個業(yè)務(wù)模塊的操作許可,那么鑒權(quán)通過,否則鑒權(quán)失敗。這種就是屬于側(cè)重前端對于用戶的控制,弱化了接口級的控制。3.角色與權(quán)限的關(guān)系
通過1,2的描述,基本確定了權(quán)限的定義和劃分一個權(quán)限的通用法則。用戶在系統(tǒng)中最終是通過權(quán)限來使用各種功能點,是否有必要在用戶和權(quán)限中間再額外的附加一個關(guān)系。在我們現(xiàn)在的權(quán)限設(shè)計中,是增加了這樣一層關(guān)系的,就是角色。
減少操作層面的重復(fù)性。角色其實就是一組權(quán)限的集合,是權(quán)限集合的更高級抽象,為了便于運維和實際管理,通過角色的賦予,替代了權(quán)限賦予用戶的繁瑣性,在一套系統(tǒng)中,普遍情況都是權(quán)限的數(shù)量多于角色的數(shù)量。
權(quán)限是控制對象和操作集合,它本身不存在任何狀態(tài),但是在賦予在用戶身上則擁有了狀態(tài),比如權(quán)限A中允許用戶訪問頁面A,權(quán)限B允許用戶訪問頁面B,權(quán)限D(zhuǎn)運行用戶訪問B頁面,但是不允許訪問A頁面。那么這層關(guān)系的維護在角色層面的話,會更加清晰,也就是說本身角色具有權(quán)限集合組裝的策略問題,對于互斥的權(quán)限有不同的方案處理。(權(quán)限中沒有某個操作和權(quán)限中禁止某個操作,是兩個不同的角度,不能混為一談)
因為權(quán)限的可能存在互斥性,在實際業(yè)務(wù)中也會引發(fā)角色的互斥性,舉一個現(xiàn)實中的案例來解釋互斥性:張三是軟件部的負(fù)責(zé)人但因為工作的特殊性也同樣隸屬于業(yè)務(wù)部的普通員工,我們設(shè)定負(fù)責(zé)人是可以要求人事部門給本部門進行招聘的,在實際的情況中,張三能給軟件部招聘新員工,但是不能給業(yè)務(wù)部招聘員工。我們把這個案例運用在系統(tǒng)中,張三則是擁有負(fù)責(zé)人和普通員工兩個角色,但是招聘的功能如果不加以控制,則會發(fā)生張三給業(yè)務(wù)部招人的結(jié)果。于是為了解決角色的這類問題,引入了職責(zé)劃分的方案。
職責(zé)劃分分為:靜態(tài)、動態(tài)。所謂靜態(tài)職責(zé)劃分則是在角色創(chuàng)建之初就已經(jīng)確定了角色的職責(zé)內(nèi)容。動態(tài)職責(zé)劃分是系統(tǒng)運行過程中對用戶已有的角色進行控制,例如:某些角色不能共存在用戶身上(互斥)、角色或角色的分配數(shù)量限定(控制用量)、角色與角色同時只能激活一個進行使用(時刻唯一)。
引入角色的概念后,實際上這已經(jīng)是一個比較完整的RBAC的權(quán)限設(shè)計的模型了。4.數(shù)據(jù)表的設(shè)計思路
根據(jù)3的結(jié)論,實質(zhì)上已經(jīng)有了一個基礎(chǔ)的表設(shè)計的雛形。在這里就有一些值得注意的點。
(1)問:權(quán)限表是否有必要存在?
(1)答:這個要結(jié)合系統(tǒng)的實際使用場景進行考慮,如果系統(tǒng)中的權(quán)限的對象很單一,比如只有頁面,或者只有api接口的話,其實權(quán)限表可有可無。增加權(quán)限表反而會導(dǎo)致初始化項目權(quán)限的工作量增加。但是若系統(tǒng)中的權(quán)限對象是多個,那么權(quán)限表的存在就有了更深層次的意義。在權(quán)限對象是多個的情況,權(quán)限表的存在就是為了更好更抽象的組合“最小特權(quán)”及“責(zé)任劃分”的操作對象。同時,一旦系統(tǒng)中的操作對象增加了,只需要給權(quán)限表增加一個對象表和關(guān)系表就可以了。這樣易于擴展。
(2)問:api接口和頁面實際上是沒有關(guān)系的,但是在鑒權(quán)活動是有關(guān)系的,頁面若和api沒有一點綁定聯(lián)系的話,服務(wù)端接口調(diào)用的時候則要么攔截掉所有指定的接口(頁面和api接口沒綁定的話,則頁面的接口調(diào)用都不能成功),服務(wù)端接口完全不攔截接口,也會不安全,但是api接口和頁面功能在表結(jié)構(gòu)層面的綁定會產(chǎn)生運維的大量工作成本,如何更好的設(shè)計。
(2)答:在權(quán)限如何劃分中已經(jīng)提過了這一點,在表結(jié)構(gòu)中,我們可以增加一張業(yè)務(wù)模塊表和操作表(也可以在數(shù)據(jù)字典表中增加這兩類數(shù)據(jù)),我們可以在頁面和功能點鐘 綁定業(yè)務(wù)模塊和操作表關(guān)系,在api接口的代碼層面去綁定業(yè)務(wù)模塊和操作,在邏輯上綁定關(guān)系,解耦表結(jié)構(gòu)之間的關(guān)系,那么可以在一定程度上解決這一點,這樣做只會出現(xiàn)一種問題,那就是用戶訪問頁面的時候可調(diào)用的api接口會比實際可調(diào)用的接口數(shù)要多,但是前端權(quán)限管理會隱藏功能點,這樣就在可視化的程度上解決了這個問題。
5.安全框架由于我們是基于RBAC的權(quán)限設(shè)計,現(xiàn)行java框架下最常見的就是shiro和Spring Security 。這兩個就是仁者見仁智者見智了,我兩者都實用過。僅建議使用shiro的話,可以更好的理解RBAC的設(shè)計思路,Spring Security 也是個不錯的框架,但是它涉及到的概念太多,并不利于初學(xué)者去了解最基本的權(quán)限設(shè)計。我在這只在學(xué)習(xí)的角度上去比較這兩個框架,并沒有再其他領(lǐng)域去做比較,也不去比較。引用的文章
[權(quán)限系統(tǒng)與RBAC模型概述[絕對經(jīng)典]](https://blog.csdn.net/yangwen...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/76642.html
摘要:的自身注解的用法。所以自定義注解的作用很廣。但是在這里,我僅僅基于的來實現(xiàn)適用于它的自定義注解。其他的自定義的注解的編寫思路和這個也是類似的。 基于shiro的自定義注解的擴展 根據(jù)我的上一篇文章,權(quán)限設(shè)計的雜談中,涉及到了有關(guān)于前后端分離中,頁面和api接口斷開表與表層面的關(guān)聯(lián),另辟蹊徑從其他角度找到方式進行關(guān)聯(lián)。這里我們主要采取了shiro的自定義注解的方案。本篇文章主要解決以下的...
摘要:背景很多時候我們需要用來作為一些標(biāo)識比如一個用戶登錄后的認(rèn)證標(biāo)識實現(xiàn)方式的方式自己定義的需要的值這里用隨機串作為執(zhí)行結(jié)果看著不是很舒服作為強迫癥的我是受不了的的方式執(zhí)行結(jié)果看著稍微舒服些了但是還不夠好反觀微信的一般是不會有后面的號的優(yōu)化執(zhí)行 背景 很多時候我們需要用 token 來作為一些標(biāo)識, 比如: 一個用戶登錄后的認(rèn)證標(biāo)識. 實現(xiàn)方式 md5 的方式: $v = 1; // 自己...
摘要:對的請求,也是要有一個了解,比如協(xié)議,請求方式,請求過程,結(jié)果狀態(tài)碼等。教程協(xié)議詳解經(jīng)典面試題一個故事講完響應(yīng)狀態(tài)碼上面提到響應(yīng)狀態(tài)碼,在這里也簡單寫下。 勸了別人無數(shù)次,讓別人喝了雞湯,幫別人填坑,自己卻掉了坑 1.前言 在前端學(xué)習(xí)里面,很多人都是注重學(xué)習(xí)代碼(html,css,js)?;蛘呤且恍┛蚣?,庫(jquery,vue,react),或者是各種工具(webpack,gulp)...
閱讀 2277·2021-11-23 09:51
閱讀 1110·2021-11-22 15:35
閱讀 5028·2021-11-22 09:34
閱讀 1674·2021-10-08 10:13
閱讀 3043·2021-07-22 17:35
閱讀 2612·2019-08-30 15:56
閱讀 3114·2019-08-29 18:44
閱讀 3140·2019-08-29 15:32