如何記錄一個權限呢,比如一個使用者,他有一個權限值,最大可表示為2的64次方減1,是以,這個值有64個二進制位,那麼,每一位要麼是0,要麼是1,是以,如果每一位表示一種權限的話,就可以表示64種權限了,是以,隻要對指定的一位進行判斷是0還是1,就可以驗證使用者的權限了。對于每一個操作的權限值,可以用一個二進制數來表示,每個權限值,隻能是(0),(10),(100),(1000),也就是說,是2的N次方,在MSSQL2000中,最大的整數是bigint類型的,最大可以表示64種操作。當然,這個是遠遠不夠的。是以可以給權限分組。比如,可分為文員,主管,經理,那麼,我們最多可以分64個組,N0到N64組,第N個組的權限值(rolevalue)就可以用2的N-1次方來表示,是以,可以表示64個權限組了。這樣,不同的使用者,可以屬于1個或是多個權限組,一個權限組,可能包括多個使用者,同理,對于一個操作,可能會屬于多個權限組,一個權限組,肯定要包括多個操作。是以,使用者與操作是通過權限組聯系以一起的。權限組與使用者,與操作之間的對應關系,都是一對多的關系。
現在說說用C#來實作,不是在SQL中實作。
在資料庫中的表:
操作組:
opname oprolevalue
填寫 3
修改 3
删除 11
送出 6
稽核 12
權限組:
rolename rolevalue
文員 1
主管 2
經理 4
總監 8
使用者資訊:
username userrolevalue
u1 5
在C#中:
Long userrolevalue ;//使用者的權限值,根據他屬于的權限組,這個值會不同
Long oprolevalue ;//一個操作的權限值,根據他屬于的權限組,這個值會不同
1、權限的賦予(或運算)
userrolevalue = userrolevalue | oprolevalue
假設一個使用者u1,他的初始權限值為0(00000000)。如果要指定他有經理的權限,經理的權限值為4(00000100),在第三個二進制位為1。
很顯然,userrolevalue = 0 | 4 ,值為4,如果u1要同時具有文員、主管、經理的權限呢,
userrolevalue = 0 | 1 00000000 | 00000001 = 00000001
userrolevalue = 1 | 2 00000001 | 00000010 = 00000011
userrolevalue = 3 | 4 00000011 | 00000100 = 00000111
這樣,第1、2、3位都是1了,用 “或”的好處就是隻改變指定位的值,如果使用者已經有了該權限,再賦予一次,也不會出錯,但是直接簡單的用加法來做,這會出錯了,如下:
userrolevalue = 7 | 4 00000111 | 00000100 = 00000111
2、權限的除去(求補、與運算)
userrolevalue = userrolevalue & (~oprolevalue)
假設一個使用者u1,他的初始權限值為7(00000111),說明他能做文員、主管、經理權限組所能作的所有操作。如果不想讓他有主管權限組能作的操作呢,那麼,就要把他的權限值變為00000101,而主管權限組的權限值是00000010,顯然簡單的用減法,肯定也是不行的,但是先對00000010作補運算,可以得到11111101,再同00000111作與運算,就得到了00000101,這樣就隻對第二位作了改變,不會影響到其它位,我們的目的也就達到了。
對于一個操作,哪些權限組能操作它,也可以用與運算來做,不讓某些權限組有些操作的權限,也可以先求補,再作與運算來解決。
3、權限的驗證(與運算)
(userrolevalue & oprolevalue) != 0
對于某使用者,有沒有某操作的權限,隻要判斷它們兩個是不是屬于同一個,或多個權限組就可以了,是以用與運算就最合适不過了。
比如u1使用者,他的權限值是5(文員組、經理組00000101),對于填寫操作的權限值是00000011,說明對于文員組與主管組有填寫的權限。
因為 00000101 & 00000011 == 1。對于一個文員,他隻屬于文員組,他的權限值肯定是00000001了,對于送出操作00000110,因為00000101 &00000001 == 0,是以,他也就沒有送出操作的權限了。
此的驗證方法,還可以用在菜單權限的驗證上來。權限值還可以是Binary資料類型的,此類型的位數可以很大,是以可以用作不分權限組的情況。