天天看點

權限管理----MIS系統案例分析

但凡涉及多使用者不同權限的網絡或者單機程式,都會有權限管理的問題,比較突出的是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,這樣,我們通過權限累加的辦法就可以輕易的将原本要分為幾條記錄描述的權限放在一起了,例如,假定某使用者ID為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,即表示,該使用者具有了對庫存表錄入+浏覽+修改+删除權限。

當然,對權限清單我們使用上述方法的前提是權限清單記錄條數不會太多并且關系不是十分複雜,否則,光是解析權限代碼就要機器忽悠半宿:)

我希望以上的分析是正确且有效的(事實上,我也用這些的方法在不止一套系統中實作),但無論如何,我覺得如此實作權限管理,隻是考慮了資料庫設計和應用程式接口兩部分内容,對于實作,還是顯得很費勁。是以,我懇請有過類似設計、實作經驗的同志們提出建設性的意見和修改建議。

另外,關于資料庫設計的思路還有使用二維表的,這将在以後的時間裡讨論,關于應用程式接口的設計和實作我也将在利用另外篇幅和大家共同探讨,代碼将用類C文法實作(我不喜歡pascal,抱歉)

繼續閱讀