久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

[七年技術(shù)總結(jié)系列][理論篇]-RBAC權(quán)限模型由淺入深

 小世界的野孩子 2021-07-30

權(quán)限部分將分兩章介紹,,第一章由淺入深介紹權(quán)限理論知識及應(yīng)用,,第二章介紹具體實現(xiàn)。后期再講述中間件的使用時,,還會插入一些權(quán)限內(nèi)容,,本質(zhì)上屬于中間件的應(yīng)用。

權(quán)限模塊是業(yè)務(wù)系統(tǒng)最常見,、最基本的子集,。本章假定了一個系統(tǒng)從最初簡單的需求到逐漸成熟且完善的權(quán)限體系的實現(xiàn)過程。

閱讀本章預(yù)計花費20分鐘,。

1. 最簡單的權(quán)限模型

業(yè)務(wù)系統(tǒng)初期,,需求簡單,,對于權(quán)限的內(nèi)容本身并不復(fù)雜,我們假設(shè)權(quán)限部分僅有這樣簡單的需求:

能給用戶賦予數(shù)據(jù)的增,、刪,、改、查四種權(quán)限

分析此需求,,權(quán)限的主體為用戶,,權(quán)限的內(nèi)容有多種,關(guān)系為M - M,,具體為:
用戶模型:

public class User
{
    public int UserId{ get; set; }
    public string UserName { get; set; }
}

用戶表Auth_User

字段 類型 說明
*UserId int 用戶ID
UserName varchar 用戶名
... ... ...

權(quán)限枚舉:

[Flags]
public enum Permission
{
    Add = 1,
    Update = 2,
    Delete = 4,
    Select = 8
}

權(quán)限表 Auth_Permission

字段 類型 說明
*PermissionId int 權(quán)限ID
Permission varchar 權(quán)限內(nèi)容

用戶-權(quán)限關(guān)系表 Auth_UserPermission

字段 類型 說明
*UserId int 用戶ID
*PermissionId int 權(quán)限ID

假如一個用戶有增,、改兩種權(quán)限,那么關(guān)系表(Auth_UserPermission)可以存儲為:

UserId Permission
1 1
1 2

于是對于權(quán)限的基本操作我們可以進行歸納:

  • 授權(quán):INSERT 權(quán)限表 (用戶ID,權(quán)限的具體值)
  • 校權(quán):EXISTS 權(quán)限表 UserID==用戶ID AND Permission==要判斷權(quán)限的具體值

我們留意到對于Permission的枚舉定義,,值使用了對2的冪運算的值:

冪運算 十進制 二進制 十六進制
2^0 1 0001 0x01
2^1 2 0010 0x02
2^2 4 0100 0x04
2^3 8 1000 0x08

這么定義是有好處的,,對于Auth_UserPermission的表存儲可以節(jié)省存儲空間,并且程序便于處理,,譬如:
如果UserId=1的用戶擁有Add,、Select權(quán)限,Auth_UserPermission表原本應(yīng)該存儲兩條記錄:

  • (1,1)
  • (1,8)

現(xiàn)在,,可以考慮更簡單的存儲方式

  • (1,9)

這表示:
Permission.Add | Permission.Select
等價于
1 按位或 8 ( 1 | 8 )
等價于
9

而對于權(quán)限的判斷,,則使用存儲的權(quán)限值按位與要進行校權(quán)的值是否等于要進行校權(quán)的值來判斷
譬如判斷用戶是否擁有Delete權(quán)限,則使用9按位與4是否等于4來進行判斷,,用C#的三目運算來表示為:

9 & 4 == 4 ? "有權(quán)限":"無權(quán)限"

這樣被標記有Flags特性的枚舉在.Net框架中遍布各種基礎(chǔ)類庫,,譬如反射中的BindFlags枚舉。本身屬于基礎(chǔ)知識,,由于不常應(yīng)用所以容易被忽視,,在權(quán)限中屬于應(yīng)用小技巧。還有人質(zhì)疑這么存儲會有性能問題,,在后面章節(jié)講到優(yōu)化時,,再行討論。

于是我們對使用了小技巧的新的權(quán)限基本控制再次進行歸納:

  • 授權(quán):INSERT 權(quán)限表(用戶ID,所有擁有權(quán)限的按位或值)
  • 校權(quán):EXISTS 權(quán)限表(UserID == 用戶ID AND Permission & 要判斷權(quán)限的具體值 == 要判斷權(quán)限的具體值)

2. 基于角色的基本權(quán)限控制

隨著業(yè)務(wù)系統(tǒng)的發(fā)展,,業(yè)務(wù)系統(tǒng)有了第一次升級機會,,并附帶了一個新的權(quán)限需求:

系統(tǒng)需要滿足一類職位的人擁有相同的權(quán)限

按照第一節(jié)的內(nèi)容,這個需求其實不用做任何變化一樣可以滿足,,但是問題在于負責(zé)授權(quán)的人“太累了”,,對于每一個用戶,我們可能都要做一遍授權(quán)的操作,。
為了解決這個問題,我們引入角色這一基本單元,,角色是一種抽象,,可以具體到業(yè)務(wù)場景的類似職位,、身份等概念。

角色模型設(shè)計:

public class Role
{
    public int RoleId { get;set; }
    public string RoleName { get;set; }
}

角色表設(shè)計Auth_Role:

字段 類型 說明
*RoleId int 角色ID
RoleName varchar 角色名稱

基于角色的基本權(quán)限控制的原則是:

  1. 簡化用戶權(quán)限的操作,;
  2. 權(quán)限操作的對象從用戶變更為角色,;
  3. 不能對單一用戶做權(quán)限操作,僅對角色做權(quán)限操作,,每個需要權(quán)限的用戶,,都擁有至少一個角色;

角色與用戶的抽象關(guān)系表現(xiàn)為M-M,,這表示:

  • 一個用戶可以擁有多個角色,;
  • 一個角色下有多個用戶;

具體到業(yè)務(wù)可以是一個人可以有多個職位,;一個職位下有多個人,;
針對此設(shè)計,我們需要做以下操作:

  1. 從系統(tǒng)中刪除掉原來的Auth_UserPermission關(guān)系,;
  2. 新增Auth_UserRole(UserId,RoleId)的關(guān)系,;
  3. 新增Auth_RolePermission(RoleId,Permission)的關(guān)系;

假定業(yè)務(wù)系統(tǒng)有這樣的職位列表:

RoleId RoleName
1 總裁
2 開發(fā)總監(jiān)

假設(shè)用戶ID等于1001的用戶職位為總裁兼開發(fā)總監(jiān),,那么關(guān)系表Auth_UserRole可以存儲為:

UserId RoleId
1001 1
1001 2

業(yè)務(wù)約定:總裁有增,、刪、改,、查四個權(quán)限,,開發(fā)總監(jiān)則有增、查兩個權(quán)限,,那么關(guān)系表Auth_RolePermission可以存儲為:

RoleId Permission
1 15( = 1 | 2 | 4 | 8 )
2 9

我們對給予角色的基本權(quán)限控制操作再次歸納為:

  • 授權(quán):給角色添加權(quán)限(INSERT Auth_RolePermission),,給用戶添加角色(INSERT Auth_UserRole)
  • 校權(quán):應(yīng)當(dāng)是拿出用戶所有的角色,并再次拿出這些角色的權(quán)限做并集,,并DISTINCT 權(quán)限并集為權(quán)限集合,,判斷權(quán)限集合是否含有需要校權(quán)的權(quán)限

3. 基于角色并含有用戶組概念的權(quán)限控制

春去秋來,業(yè)務(wù)系統(tǒng)迎來了第二次升級機會,,并包含以下新的權(quán)限需求:

所有部門的開發(fā)崗位擁有相同的增,、查權(quán)限

基于第二節(jié)的系統(tǒng)升級,解決此需求我們會有臨時的做法:做一個角色,,給所有開發(fā)崗的同事賦予這個角色,。

這樣的臨時做法的確解決了我們的問題,但這里有幾個問題,,函待解決:

  1. 系統(tǒng)沒有部門的對應(yīng)抽象,;
  2. 一旦其中一個部門的開發(fā)崗?fù)聯(lián)碛械臋?quán)限有變動,我們需要新建角色,并重新授權(quán),;

針對此兩個問題,,我們引入一個新的模型:用戶組(UserGroup),用戶組的概念在業(yè)務(wù)系統(tǒng)中,,可以具體為:部門,、小組、團隊等

用戶組模型設(shè)計:

public class UserGroup
{
    public int UserGroupId { get; set; }
    public int ParentId { get;set; } //留意此字段,,將在本節(jié)末尾闡述
    public string UserGroupName { get; set; }
}

用戶組表Auth_UserGroup設(shè)計:

字段 類型 說明
*UserGroupId int 部門ID
ParentId int 上級部門ID
UserGroupName varchar 部門名稱

基于角色并含有用戶組概念的權(quán)限控制有以下特點:

  1. 再次簡化了用戶權(quán)限的操作,;
  2. 用戶可以擁有角色;用戶組也可以擁有角色,;
  3. 權(quán)限的操作對象依舊為角色,,不可對用戶、用戶組進行權(quán)限操作,;

用戶與用戶組的關(guān)系表現(xiàn)為多對多,,這表示一個用戶可以屬于多個用戶組,一個用戶組下可以有多個用戶,,具體到業(yè)務(wù)可以描述為:一個人可以在多個部門,,一個部門下可以有多個人;

用戶組與角色的關(guān)系表現(xiàn)為多對多,,這表示一個用戶組的所有用戶可以擁有相同的多個角色,,一個角色下有多個用戶組,具體到業(yè)務(wù)可以描述為:同一個部門的人可以擁有多個相同的職位,;

為了實現(xiàn)此設(shè)計,,我們需要做以下新的操作:

  1. 新增Auth_UserUserGroup關(guān)系;
  2. 新增Auth_UserGroupRole關(guān)系,;

假設(shè)系統(tǒng)擁有這樣的部門列表:

UserGroupId UserGroupName
1 總裁辦
2 前端開發(fā)部
3 中臺開發(fā)部
4 人力資源部
5 保安部

假設(shè)用戶ID為1101的用戶既是前端開發(fā)部的開發(fā)總監(jiān),,又是中臺開發(fā)部的開發(fā)總監(jiān);中臺開發(fā)部,、前端開發(fā)部的所有同事本質(zhì)都是開發(fā),,且所有開發(fā)部的同事都有增、查的權(quán)限,,那么:

用戶-用戶組Auth_UserUserGroup關(guān)系表可以存儲為:

UserId UserGroupId
1101 2
1101 3

新增角色:開發(fā)

RoleId RoleName
6 開發(fā)

Auth_RolePermission新增記錄:

RoleId Permission
6 9

Auth_UserGroupRole關(guān)系表可以存儲為:

UserGroupId RoleId
2 6
3 6

這樣,,我們就滿足了本節(jié)提出的需求。
另外要注意到的是用戶組的ParentId字段,,不要輕視這個簡單的樹狀設(shè)計,,實際應(yīng)用中根據(jù)業(yè)務(wù)場景會有各種不同的問題,譬如不良的SQL導(dǎo)致DB層面做了遞歸查詢,、上級部門權(quán)限與下級部門權(quán)限的繼承關(guān)系,,但這本質(zhì)屬于業(yè)務(wù)需求,,不再贅述

4. RBAC權(quán)限模型

現(xiàn)在,系統(tǒng)經(jīng)過3次升級,,已經(jīng)有了較為完備的權(quán)限體系,,我們解決了大部分問題。
但是我們也注意到,,所有的有關(guān)于權(quán)限的定義僅僅圍繞著增刪改查這一類權(quán)限控制。假如系統(tǒng)現(xiàn)在需要多控制一部分權(quán)限內(nèi)容,,我們就有些捉襟見肘了,。

簡單來說,我們的權(quán)限模型設(shè)計對于擴展支持不夠

譬如,,業(yè)務(wù)系統(tǒng)初期對系統(tǒng)的菜單可見性有權(quán)限控制,,隨著系統(tǒng)迭代,可能出現(xiàn)對文件的可操作性也需要有權(quán)限控制,,這是很正常的事,,顯然,依照我們的設(shè)計,,系統(tǒng)無法滿足,。

回顧1、2,、3節(jié)的升級內(nèi)容,,我們的問題其實是由單一權(quán)限元素變更為多元權(quán)限元素,如果我們能重新將被控制元素變更為單一元素,,我們之前的設(shè)計則不用變更,。

為了解決這個問題,我們對各種權(quán)限元素進行抽象,,譬如文件訪問權(quán)限和菜單訪問權(quán)限,。抽象為如下圖內(nèi)容:

現(xiàn)在,權(quán)限的Root節(jié)點變成了Permission這個抽象,,它沒有具體的意義,,但他將各類權(quán)限集中在了一起,使得多種權(quán)限元素重新集中在單一Permission這個抽象元素上,,再次揉入到我們的系統(tǒng)中,,如下圖:

這就是權(quán)限系統(tǒng)的RBAC完成模型。

至此,,借助RBAC模型,,我們完成了權(quán)限模塊的理論設(shè)計,它能滿足大量權(quán)限控制場景,,也是業(yè)界慣用的手段,,RBAC模型是一種權(quán)限模型的總結(jié)和歸納,,市面上能見到的各種權(quán)限控制,都與RBAC沾邊,,也就是說,,掌握RBAC,就掌握了閱讀各種系統(tǒng)權(quán)限設(shè)計的基礎(chǔ),,有了理論支持,。

不過值得注意的是,雖然我們有了理論基礎(chǔ),,但實際應(yīng)用中,,我們還要做一些擴展內(nèi)容。

譬如說權(quán)限歷史,,權(quán)限模塊屬于敏感內(nèi)容,,是系統(tǒng)的中樞所在,嚴謹?shù)臋?quán)限模塊肯定是不會對操作進行Delete的,,而是Fake Delete以保留歷史,。上文中這樣的設(shè)計為此提供了方便,當(dāng)用戶的權(quán)限發(fā)生變更時,,我們只需要對關(guān)系做Fake Delete即可,。當(dāng)然,關(guān)系本身需具備IsFakeDeleted屬性,。

下一章節(jié)將介紹dotnet core的具體實現(xiàn),。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多