按照計劃本暑假進(jìn)行點名系統(tǒng)的大型更新乔妈,其一重頭戲就是強化權(quán)限體系辞嗡,加入角色的概念捆等。如何優(yōu)雅、高效地實現(xiàn)權(quán)限認(rèn)證成了一個棘手的問題续室。參考網(wǎng)上部分文章栋烤,初步計劃應(yīng)用下面的設(shè)計。在此整理記錄一下挺狰。
基本思路
“角色”是權(quán)限的最小單位明郭,所有用戶必須關(guān)聯(lián)角色,不允許直接賦予權(quán)限丰泊。一個用戶可以關(guān)聯(lián)多個角色薯定,其權(quán)限取并集。
每個角色可以包含各種權(quán)限瞳购。
用“位”表示權(quán)限
最簡單粗暴的權(quán)限記錄形式就是列表话侄,例如如下一個用于記錄權(quán)限的數(shù)據(jù)表:
[Table:permission]
Id | UserName | Permission |
---|---|---|
0 | aaa | LEAVE_BROWSE |
1 | aaa | LEAVE_ADD |
2 | aaa | LEAVE_DEL |
3 | bbb | LEAVE_BROWSE |
此種記錄方法雖簡單直觀,但冗余數(shù)據(jù)過多,每一次判斷權(quán)限都需要查詢一遍整個表年堆,性能差吞杭,尤其在用戶與權(quán)限種類較多的時候。
用“位”表示權(quán)限的理論基礎(chǔ)是超遞增序列:1,2,4,8,16……变丧,即:2^n(n>=0)芽狗。此數(shù)列有這樣一個特性:拼出的任意一個和數(shù)一定可以由這個序列中的一些數(shù)構(gòu)成,且構(gòu)成方法唯一痒蓬。例如:20=16+4且只有16和4可以拼出20.借助這個特性我們可以用來表示權(quán)限童擎。
首先建立權(quán)限內(nèi)容與編號的對應(yīng)關(guān)系(可寫為常量或xml或其他任意類型):
編號(為2^n) | 說明 |
---|---|
1 | 讀取請假列表 |
2 | 添加請假列表 |
4 | 刪除請假列表 |
假設(shè)用戶aaa同時具有讀取與添加請假列表的權(quán)限,只需要將他的權(quán)值設(shè)為1+2=3即可谊却。
如此一來柔昼,上述的權(quán)限表甚至可以刪掉,直接集成在用戶表里就夠了:
[Table:user]
UserName | Permission | ...OtherFields |
---|---|---|
aaa | 7 | ... |
bbb | 1 | ... |
…… | …… | …… |
判斷權(quán)限
如果我們知道用戶aaa的權(quán)值為3炎辨,如何判斷他是否具有某一權(quán)限呢捕透?
很簡單,只需要進(jìn)行位與運算即可碴萧。若結(jié)果不為0則表示具有此權(quán)限乙嘀。
例如:
3D=011B;1D=001B破喻;2D=010B虎谢;4D=100B
011B & 010B = 010B ≠ 0,則具有添加權(quán)限曹质。
011B & 100B = 000B婴噩,則不具有刪除權(quán)限。
增加權(quán)限
那么如果在已有權(quán)限基礎(chǔ)上增加一個權(quán)限呢羽德?
只需進(jìn)行位或即可几莽。
例如:
011B | 100B = 111B = 7D
在讀取與添加的基礎(chǔ)上增加了刪除權(quán)限。
同時發(fā)現(xiàn)7=1+2+4宅静,與上述超遞增序列的定義是一致的
刪除權(quán)限
當(dāng)然章蚣,有時我們也需要剝奪某人的一些權(quán)限。
只要與上按位取反即可姨夹。
例如:
111B &~ 010B = 101B = 5D
此時剝奪了添加權(quán)限纤垂,只剩讀取、刪除權(quán)限了磷账。
范圍問題
不難看出峭沦,此處的權(quán)值是個整數(shù),一般情況下應(yīng)該會習(xí)慣性地用int存儲逃糟,這樣問題就來了熙侍,int一般情況下只能表示2^32,如果權(quán)限種類大于32該如何是好。
權(quán)限分組
未完待續(xù)蛉抓。庆尘。。