1. 程式人生 > >PBAC基於策略的許可權控制

PBAC基於策略的許可權控制

PBAC思想

要解決的問題?

在pb實現一般管理系統的時候,我們會遇到這樣一種情況,作為一個系統,可以分為若干個子系統,有多個操作員對它進行操作,每個操作員對各個子系統的許可權不同,甚至在同一子系統中,操作員對各個選單項的操作許可權也不一樣,更細一點,不同的操作員對於同一視窗中某一按鈕的操作許可權也是不一樣的,那麼,怎樣較好地實現對不同使用者細化到某個按鈕的許可權控制呢?

思路

1.舉例

首先,怎樣使得一個操作員不能對他不具許可權的選單項或按鈕進行操作呢,我們當然沒有必要為不同的使用者製作不同的選單項或視窗(當然這也不失為一種方法),考慮到選單項和按鈕的Visible和Enabled屬性,我們自然想到,設定這兩個屬性便可以完成上面的要求,比如
m_1.m_2.visible=false 或者 cb_1.enabled=false 選單不可見了,操作員自然就不可操作了。

2.如何存放

其次,對於一個多使用者的系統,我們自然需要用一個表來存放基本的使用者資訊,其中要包括使用者登入系統的使用者名稱、密碼,如果要進行許可權的分級控制,還需要一些欄位來存放有關許可權的資訊,有些成品系統中是這樣做的,不過它們將每個需要進行控制的選單項均用一個欄位來表示,這樣做不太好,萬一設計一個許可權控制比較細的系統時,這樣做的可行性便不好,其實,對與某個選單項或其他控制元件,進行許可權控制時,狀態只有兩個,true
or
false,完全可以用一位二進位制數0或1來表示,我們可以將一個子系統中所有需要進行許可權控制的項組合成一個二進位制串,每四個二進位制數轉化成一個字元(可以是
“0”,”1”,”2”….”a”,”b”,”c”,”d”,”e”,”f”),再儲存在表中,這樣我們來算一下,如果一個子系統中有64個項需要進行許可權控制,則只需要一個
64/4=16 位的字元型別的欄位即可以表示,而不像過去那樣需要64個欄位來分別標記。

3.如何控制

好了,第一步存放的問題解決了,那麼怎樣根據這樣的一個標記許可權的字串來設定各個選單項或其他控制元件的visible
或Enabled屬性呢?我注意到,pb中選單項和其它控制元件都有一個tag屬性,而這個屬性我們一般不太會用到它,我們可以用tag屬性來存放一個數字,這個數字標示了該控制元件在許可權控制欄位的那個二進位制串中表示該控制元件的訪問許可權的0/1的位置,舉個例子,有一個許可權控制二進位制串’01001111010….’,選單項”開啟檔案”的tag為7,則在該二進位制串中第7位”1”便標記了當前使用者對”開啟檔案”的控制權限為”1”. 當一個使用者登入系統時,在通過了密碼驗證後,將他對該系統的許可權控制欄位的字串讀到一個全域性變數中,將該字串恢復為0、1串,對於每個需要進行許可權控制的項,依次根據其tag記錄的相應位置的0或1設定Visible或Enabled屬性,便可以完成對許可權的管理。
當然,要注意的是,有些控制元件的許可權設定並不是在一進入系統後就進行的,而是推遲到該控制元件被呼叫時才進行。

下面給出了一個例子,來說明上面的論述。

有以下3個選單項和2個按鈕需要控制 3個選單項名稱分別為: m_a.m_h1.m_m1 m_a.m_h1.m_m2
m_a.m_h1.m_m3 以上3個選單項的tag設定為 1-3 2個按鈕位於兩個視窗中 cb_1 位於w_1中 cb_2 位於w_2中
以上2個按鈕的tag設定為4,5 這樣,需要5位來表示他們的訪問許可權。
函式getbin用來進行從”0”,”1”…,”a”…”f”到四位二進位制串的轉換

getbin(string s_ch) returns string
string s_out,s_temp
integer i_len
integer i
string temp
i_len=len(s_ch)
if i_len=0 or isnull(s_ch) then
s_out="0"
end if
temp=""
s_temp=""
for i=1 to i_len 
temp=mid(s_ch,i,1)
choose case lower(temp)
case "a" 
s_temp="1010"
case "b"
s_temp="1011"
case "c"
s_temp="1100"
case "d"
s_temp="1101"
case "e"
s_temp="1110"
case "f"
s_temp="1111"
case "0"
s_temp="0000"
case "1"
s_temp="0001"
case "2"
s_temp="0010"
case "3"
s_temp="0011"
case "4"
s_temp="0100"
case "5"
s_temp="0101"
case "6"
s_temp="0110"
case "7"
s_temp="0111"
case "8"
s_temp="1000"
case "9"
s_temp="1001"
case else
s_temp="0000"
end choose
s_out=s_out+s_temp
s_temp=""
next
return s_out

定義一個全域性變數s_admin用來存放該使用者登入後的許可權資訊:
String s_temp
select rights into :s_temp where user=:username and password=:userpassword;
s_admin=getbin(s_temp) //s_admin存放的是已經轉化好的許可權資訊。

定義一個許可權函式check來完成從 0、1 到true、false 的轉換。
check(string menutag) returns boolean
string s_temp
s_temp=mid(s_admin,integer(menutag),1) //s_admin為全域性變數
if isnull(s_temp) or s_temp=”1” then
return true
else
return false
end if
假設w_main為登入後的主視窗,它的選單為m_a
則在w_main的open事件中這樣寫:
m_a.m_h1.m_m1.enabled=check(m_a.m_h1.m_m1.tag)
m_a.m_h1.m_m2.enabled=check(m_a.m_h1.m_m2.tag)
m_a.m_h1.m_m3.enabled=check(m_a.m_h1.m_m3.tag)
在w_1的open事件中:
cb_1.enabled=check(cb_1.tag)
同樣,在w_2的open事件中
cb_2.enabled=check(cb_2.tag)
這樣就可以完成對上述5項的控制。
當然,這種方法在需要控制的項很多時(達到幾十項)的效果才比較明顯。
以上論述了許可權控制的實現,在多使用者系統中,還需要有對使用者許可權的設定功能,這個和上面是一個相反的過程.

此文章為本人筆記,亂別吐槽

轉載第三方