要實現(xiàn)權(quán)限驗證,首先必須有對具體權(quán)限的定義。在沒有RBAC的情況下,一些簡單的系統(tǒng)是把權(quán)限定義直接寫死,整個系統(tǒng)有幾種角色都提前定義好,在使用中只能給用戶分配固定的角色。編程時,哪個模塊需要做權(quán)限驗證,就在哪個模塊中直接編寫代碼,根據(jù)用戶所屬角色來設(shè)定用戶在模塊中具有的權(quán)限。這樣的方法實現(xiàn)起來最簡單,但也是最不靈活的,因為每個涉及到權(quán)限控制的部分都需要編寫相應(yīng)的判定代碼。如果新增一個新的角色,那所有涉及到權(quán)限驗證的模塊都需要增加對新角色的驗證代碼,非常不靈活。
合適的方法是在項目編程前和編程過程中,定義出來系統(tǒng)中共有多少模塊,每個模塊涉及到有什么權(quán)限,最后匯總出一個總的權(quán)限列表來。在使用中可以由用戶自己定義角色及角色權(quán)限。這樣在編程時,判斷當(dāng)前用戶是否有權(quán)調(diào)用某項權(quán)限時,只要判斷一下用戶所屬角色是否具有此權(quán)限即可??梢酝ㄟ^一個通用的驗證模塊來完成權(quán)限驗證工作,也簡化了編程工作。如下圖這個示例,首先定義出了所有權(quán)限并存儲于數(shù)據(jù)庫中,然后定義角色、角色具有的各項權(quán)限、角色所屬用戶,也存儲到數(shù)據(jù)庫中。這樣在使用中涉及到某項權(quán)限,如使用“客戶查詢”時,通過驗證模塊就能判斷出當(dāng)前用戶是否有權(quán)使用,如果有則進入,沒有則退出。此種方法的缺點是系統(tǒng)規(guī)模較大或權(quán)限設(shè)定較細的情況下,需要定義的權(quán)限非常多,會大大增加編程工作量。
說了這么多后,該說一下本系統(tǒng)的實現(xiàn)原理了。首先還是權(quán)限的定義,但此處權(quán)限不是直接定義的,而是通過“資源-操作”組合對來定義。
首先需要定義出系統(tǒng)中涉及到的所有資源(ksRBAC_Resources表和ksRBAC_ResourceGroups表)。如庫存管理中的倉庫、車輛,銷售系統(tǒng)中的商品、柜組等。每一項內(nèi)容都可以定義成一項資源,且可以無限細分。在這里,還引入了資源組的概念,通過資源組及下屬資源組的劃分,使不同資源能夠進行分類歸檔,方便了資源的管理。
其次需要定義操作(ksRBAC_Operations表),操作是指允許對某項資源進行何種操作行為。如針對倉庫的操作有出庫、入庫、盤點等,針對車輛的操作有駕駛、保養(yǎng),針對商品的操作有添加、刪除、銷售、進貨、退貨等等。
有了資源與操作,就能夠定義權(quán)限了(ksRBAC_Privilgegs表)。所謂的權(quán)限,其實就是定義了可以對某項資源進行何種操作,即“資源-操作”組合對。如商品銷售是一個權(quán)限定義,駕駛汽車也是一個權(quán)限定義。具體需要定義那些權(quán)限,是根據(jù)項目的實際需要來設(shè)置的。如資產(chǎn)管理的項目,會定義駕駛汽車、保養(yǎng)汽車、報廢汽車的權(quán)限來跟蹤車輛生命周期過程,而辦公管理的項目,則只會定義駕駛汽車一項權(quán)限,因為其只關(guān)心汽車的使用而不關(guān)心保養(yǎng)問題。
定義完了權(quán)限,就該定義角色了(ksRBAC_Roles表)。本系統(tǒng)中關(guān)于角色的定義比較簡單,因為考慮到一個系統(tǒng)中的角色不會有很多,所以角色部分沒有設(shè)置分組功能。
至此,系統(tǒng)權(quán)限的基本架構(gòu)已經(jīng)完成,通過上面的各個數(shù)據(jù)表,已經(jīng)能夠很好存儲項目中所定義的各項權(quán)限、角色和授權(quán)了。
定義好角色權(quán)限后,有兩種權(quán)限驗證方式。一種是將用戶加入某個角色,在進行權(quán)限(Privilege)驗證時,首先得到用戶所屬角色,然后對此角色進行權(quán)限(Privilege)驗證。采用此種方法,由于驗證對象是角色,因此用戶只能加入一個角色,使用上不是很靈活,
本系統(tǒng)采用了另一種方法,將權(quán)限驗證對象降低為具體用戶。一個用戶,可以同時加入多個角色。在用戶登錄時,首先得到用戶所屬的角色列表,然后依次得到授權(quán)(Permission)給每個角色的權(quán)限(Privilege)集合,最后將每一項權(quán)限(Privilege)加入用戶的權(quán)限列表中。這樣在使用時,只要判斷用戶的權(quán)限列表中是否具有指定的權(quán)限(Privilege)即可完成驗證工作。
對于用戶的定義,此處涉及到了三個表。ksRBAC_User是基礎(chǔ)表,負責(zé)存儲用戶的登陸名稱和密碼等最基礎(chǔ)的信息。ksRBAC_UserMembership表為權(quán)限表,用于存儲與權(quán)限驗證有關(guān)的內(nèi)容。ksRBAC_UserDetail表是用戶基本信息表,用于存儲用戶的各種資料信息?;拘畔⒈碓陧椖恐杏捎脩糇约焊鶕?jù)實際需求定義字段內(nèi)容,保證在不同項目用戶資料不一致的情況下,此表能夠靈活適應(yīng)各種情況。
前面說了權(quán)限的存儲與驗證機制,那么在具體編程過程中,如何確定一個權(quán)限。也就是說,程序怎么知道這個模塊的這個操作表示權(quán)限A,那個模塊的那個操作就表示權(quán)限B呢?這里需要通過硬編碼來完成。
例如用戶在使用商品模塊,需要執(zhí)行入庫操作時,首先程序會拿出代表“入庫操作”這一權(quán)限的ID號,然后用此ID和用戶的權(quán)限列表進行比對,判斷其中是否存在此ID,如果有則繼續(xù)向下執(zhí)行,沒有的話則提示用戶權(quán)限不足并不再繼續(xù)。至于權(quán)限的ID號,可以從數(shù)據(jù)庫中查詢得出,在編碼時直接寫出來即可。
如果在編程時僅僅做到上面這一步,那么雖然可以實現(xiàn)系統(tǒng)所需的全部功能,但是在編程中指定權(quán)限時,還需要知道權(quán)限的ID號,非常不方便。因此實際操作中是提前定義了一個權(quán)限文件,在其中使用以權(quán)限名稱命名的字符傳來存儲權(quán)限ID號,在使用時直接輸入權(quán)限名稱,就能得到權(quán)限ID了。
說了這么多,系統(tǒng)的實現(xiàn)原理就介紹的基本差不多了。有些地方說得不是很細,會在以后的文章中展開介紹的。歡迎大家共同探討。