[摘要] 下面我要說的是MIS系統許可權管理的資料庫設計及實現,當然,這些思路也可以推廣開來應用,比如說在BBS中用來管理不同層級的使用者權限。
[關鍵字]
J2EE許可權設計詳細探討 但凡涉及多使用者不同許可權的網路或者單機程式,都會有許可權管理的問題,比較突出的是MIS系統。
下面我要說的是MIS系統許可權管理的資料庫設計及實現,當然,這些思路也可以推廣開來應用,比如說在BBS中用來管理不同層級的使用者權限。
許可權設計通常包括資料庫設計、應用程式介面(API)設計、程式實現三個部分。
這三個部分相互依存,密不可分,要實現完善的許可權管理體系,必須考慮到每一個環節可行性與複雜程度甚至執行效率。
我們將許可權分類,首先是針對資料存取的許可權,通常有錄入、瀏覽、修改、刪除四種,其次是功能,它可以包括例如統計等所有非直接資料存取操作,另外,我們還可能對一些關鍵資料表某些欄位的存取進行限制。除此,我想不出還有另外種類的權限類別。
完善的許可權設計應該具有充分的可擴充性,也就是說,系統增加了新的其它功能不應該對整個許可權管理體系帶來較大的變化,要達到這個目的,首先是資料庫設計合理,其次是應用程式介面規範。
我們先討論資料庫設計。通常我們使用關聯式資料庫,這裡不討論基於Lotus產品的許可權管理。
許可權表及相關內容大體可以用六個表來描述,如下:
1 角色(即使用者組)表:包括三個欄位,ID,角色名稱,對該角色的描述;
2 使用者表:包括三個或以上欄位,ID,使用者名稱,對該使用者的描述,其它(如地址、電話等資訊);
3 角色-使用者對應表:該表記錄使用者與角色之間的對應關係,一個使用者可以隸屬於多個角色,一個角色群組也可擁有多個使用者。包括三個欄位,ID,角色ID,使用者ID;
4 限制內容列表:該表記錄所有需要加以許可權區分限制的資料表、功能和欄位等內容及其描述,包括三個欄位,ID,名稱,描述;
5 許可權列表:該表記錄所有要加以控制的許可權,如錄入、修改、刪除、執行等,也包括三個欄位,ID,名稱,描述;
6 許可權-角色-使用者對應表:一般情況下,我們對角色/使用者所擁有的許可權做如下規定,角色擁有明令允許的許可權,其它一律禁止,使用者繼承所屬角色的全部許可權,在 此範圍內的許可權除明令禁止外全部允許,範圍外許可權除明令允許外全部禁止。該表的設計是許可權管理的重點,設計的思路也很多,可以說各有千秋,不能生搬硬套說 某種方法好。對此,我的看法是就個人情況,找自己覺得合適能解決問題的用。
先說第一種也是最容易理解的方法,設計五個欄位:ID,限制內容ID,許可權ID,角色/使用者類型(布爾型欄位,用來描述一條記錄記錄的是角色許可權還是使用者權限),角色/使用者ID,權限類別型(布爾型欄位,用來描述一條記錄表示允許還是禁止)
好了,有這六個表,根據表六,我們就可以知道某個角色/使用者到底擁有/禁止某種許可權。
或者說,這麼設計已經足夠了,我們完全實現了所需要的功能:可以對角色和使用者分別進行許可權定製,也具有相當的可擴充性,比如說增加了新功能,我們只 需要添加一條或者幾條記錄就可以,同時應用程式介面也無須改動,具有相當的可行性。但是,在程式實現的過程中,我們發現,使用這種方法並不是十分科學,例 如瀏覽某個使用者所擁有的許可權時,需要對資料庫進行多次(甚至是遞迴)查詢,極不方便。於是我們需要想其它的辦法。使用過Unix系統的人們都知道, Unix檔案系統將對檔案的操作許可權分為三種:讀、寫和執行,分別用1、2、4三個代碼標識,對使用者同時具有讀寫權限的檔案被記錄為3,即1+2。我們也
可以用類似的辦法來解決這個問題。初步的想法是修改許可權列表,加入一個欄位:標識碼,例如,我們可以將錄入許可權標識為1,瀏覽許可權標識為2,修改許可權標識 為4,刪除許可權標識為8,執行許可權標識為16,這樣,我們通過許可權累加的辦法就可以輕易的將原本要分為幾條記錄描述的許可權放在一起了,例如,假定某使用者識別碼為1,庫存表對應的限制內容ID為2,同時規定角色類型為0、使用者類型為1,我們就可以將該使用者具有錄入、瀏覽、修改、刪除庫存表的許可權描述為: 2,15,1,1。
確實很簡單,不是嗎?甚至還有更過激的辦法,將限制內容列表也加上一列,定義好標識碼,這樣,我們甚至可以用簡單的一條記錄描述某個使用者具有的對全 部內容所具有的全部許可權了。當然,這樣做的前提是限制內容數量比較小,不然,呵呵,2的n次方遞增起來可是數量驚人,不容易解析的。
從表面上看,上述方法足以達到實現功能、簡化資料庫設計及實現的複雜度這個目的,但這樣做有個弊端,我們所涉及的許可權列表不是相互獨立而是互相依賴 的,比如說修改許可權,其實是包含瀏覽許可權的,例如,我們可能只是簡單的設定使用者對庫存表存取的許可權值為錄入+修改+刪除(1+4+8=13),但事實上, 該使用者具有(1+2+4+8=15)的許可權,也就是說,在這種方案中,13=15。於是當我們調用API詢問某使用者是否具有瀏覽許可權時,就必須判斷該使用者 是否具有對該資料表的修改許可權,因此,如果不能在程式中固化許可權之間的內含項目關聯性,就不能利用應用程式介面簡單的做出判斷。但這與我們的目的“充分的可擴充
性”矛盾。
這個問題如何解決?我想到了另外一種設定標識碼的方法,那就是利用素數。我們不妨將錄入、瀏覽、修改、刪除、執行的基本標誌碼定為 2,3,5,7,11,當遇到許可權互相包含的時候,我們將它的標識碼設定為兩個(或多個)基本標誌碼的乘積,例如,可以將“修改”功能的標誌碼定為3*5 =15,然後將所有的許可權相乘,就得到了我們需要的最終許可權標識值。這樣,我們在詢問使用者是否具有某項許可權的時候,只需要將最終的值分解成質因子,例如, 我們可以定義一個使用者具有錄入+修改+刪除庫存表的許可權為 2*15*7=2*3*5*7,即表示,該使用者具有了對庫存表錄入+瀏覽+修改+刪除許可權。
當然,對許可權列表我們使用上述方法的前提是許可權列表記錄條數不會太多並且關係不是十分複雜,否則,光是解析許可權代碼就要機器忽悠半宿:)
我希望以上的分析是正確且有效(事實上,我也用這些的方法在不止一套系統中實現),但無論如何,我覺得如此實現許可權管理,只是考慮了資料庫設計和 應用程式介面兩部分內容,對於實現,還是顯得很費勁。因此,我懇請有過類似設計、實現經驗的同志們提出建設性的意見和修改建議。