將權(quán)限引入系統(tǒng)的探索
Posted on 2006-04-08 22:39 zhuweisky 閱讀(573) 評論(4) 編輯 收藏 收藏至365Key 所屬分類: WebForm 很久以前就嘗試過使用AOP進(jìn)行權(quán)限控制的管理,那時候只是試試而已,并沒有在項(xiàng)目中應(yīng)用過,最近跟的一個B/S項(xiàng)目中要求我們把權(quán)限管理加進(jìn)去,于是我考慮以前的AOP方法是否真的可行。思考許久后的結(jié)果是,可行,但是太麻煩。
主要原因在于需要在UI層<=>邏輯層<=>數(shù)據(jù)層之外增加額外的一層來使得AOP攔截可以以恰當(dāng)?shù)牧6?、恰?dāng)?shù)臅r機(jī)切入。如果不增加額外的這一層而使用AOP就可能會得到這樣的結(jié)果--比如,在業(yè)務(wù)邏輯層或數(shù)據(jù)層使用AOP切入,就有可能出現(xiàn)這樣的情形,用戶花了老大的勁將要錄入的信息敲入了,最后當(dāng)點(diǎn)擊“提交”時,系統(tǒng)卻提示說“你沒有權(quán)限進(jìn)行添加操作!”。如果你是這個用戶,你一定會郁悶得吐血!
所以,如果系統(tǒng)不允許用戶添加,則根本就不應(yīng)該讓添加的Page或Form出現(xiàn)在用戶眼前,然而,這在邏輯層或數(shù)據(jù)層是無法獲取這個信息的,只有UI層知道這是發(fā)生在什么時刻。但是,在UI層使用AOP截獲,你看見過么?我沒有,我相信那不是一件容易做的工作。
于是,我開始尋找AOP之外的方法,終于,我找到了一個自己還比較滿意的解決方案。下面我們以B/S系統(tǒng)為例,來詳細(xì)描述這個方案,如果是C/S系統(tǒng),可以類推之。
為了構(gòu)建一個在不同B/S系統(tǒng)中可以復(fù)用的解決方案,我們需要規(guī)范化(定義)一些基礎(chǔ)設(shè)施或元素。首先,我們需要定義權(quán)限的類別,比如最常見的有瀏覽、添加、修改、刪除。你也許已經(jīng)想到使用一個枚舉就可以了。但是,不能使用枚舉,因?yàn)槊杜e是sealed,不能被繼承,這就意味著權(quán)限類別將不能被自定義擴(kuò)展,所以,我沒有使用enum,而是使用class。
主要原因在于需要在UI層<=>邏輯層<=>數(shù)據(jù)層之外增加額外的一層來使得AOP攔截可以以恰當(dāng)?shù)牧6?、恰?dāng)?shù)臅r機(jī)切入。如果不增加額外的這一層而使用AOP就可能會得到這樣的結(jié)果--比如,在業(yè)務(wù)邏輯層或數(shù)據(jù)層使用AOP切入,就有可能出現(xiàn)這樣的情形,用戶花了老大的勁將要錄入的信息敲入了,最后當(dāng)點(diǎn)擊“提交”時,系統(tǒng)卻提示說“你沒有權(quán)限進(jìn)行添加操作!”。如果你是這個用戶,你一定會郁悶得吐血!
所以,如果系統(tǒng)不允許用戶添加,則根本就不應(yīng)該讓添加的Page或Form出現(xiàn)在用戶眼前,然而,這在邏輯層或數(shù)據(jù)層是無法獲取這個信息的,只有UI層知道這是發(fā)生在什么時刻。但是,在UI層使用AOP截獲,你看見過么?我沒有,我相信那不是一件容易做的工作。
于是,我開始尋找AOP之外的方法,終于,我找到了一個自己還比較滿意的解決方案。下面我們以B/S系統(tǒng)為例,來詳細(xì)描述這個方案,如果是C/S系統(tǒng),可以類推之。
為了構(gòu)建一個在不同B/S系統(tǒng)中可以復(fù)用的解決方案,我們需要規(guī)范化(定義)一些基礎(chǔ)設(shè)施或元素。首先,我們需要定義權(quán)限的類別,比如最常見的有瀏覽、添加、修改、刪除。你也許已經(jīng)想到使用一個枚舉就可以了。但是,不能使用枚舉,因?yàn)槊杜e是sealed,不能被繼承,這就意味著權(quán)限類別將不能被自定義擴(kuò)展,所以,我沒有使用enum,而是使用class。
/// <summary>
/// 應(yīng)用可以擴(kuò)展PermissionType,以增加其它權(quán)限類別,比如審核等
/// 自定義類別取值應(yīng)大于 5
/// </summary
public class PermissionType
{
public const int Browse = 1 ;
public const int Add = 2 ;
public const int Update = 3 ;
public const int Delete = 4 ;
}
/// 應(yīng)用可以擴(kuò)展PermissionType,以增加其它權(quán)限類別,比如審核等
/// 自定義類別取值應(yīng)大于 5
/// </summary
public class PermissionType
{
public const int Browse = 1 ;
public const int Add = 2 ;
public const int Update = 3 ;
public const int Delete = 4 ;
}
這樣,如果具體應(yīng)用中有更多的權(quán)限類別,只要從PermissionType繼承即可。比如,應(yīng)用中需要添加“審核”、“消審”的權(quán)限,則可以
public class MGPPermissionType : PermissionType
{
public const int Audit = 10 ; //審核
public const int CancelAudit = 11 ; //消審
}
{
public const int Audit = 10 ; //審核
public const int CancelAudit = 11 ; //消審
}
一個用戶所擁有的權(quán)限可以使用IPermission接庫進(jìn)行規(guī)范:
/// <summary>
/// 應(yīng)用可以擴(kuò)展IPermission,以增加其它權(quán)限類別,比如審核等
/// </summary>
public interface IPermission
{
bool CanBrowse{get ;}
bool CanAdd{get ;}
bool CanUpdate{get ;}
bool CanDelete{get ;}
}
/// 應(yīng)用可以擴(kuò)展IPermission,以增加其它權(quán)限類別,比如審核等
/// </summary>
public interface IPermission
{
bool CanBrowse{get ;}
bool CanAdd{get ;}
bool CanUpdate{get ;}
bool CanDelete{get ;}
}
如果應(yīng)用需要增加別的權(quán)限,也可以在實(shí)現(xiàn)這個接口的類中進(jìn)行擴(kuò)展,比如

GeneralPermission
#region GeneralPermission
public class GeneralPermission :IPermission
{
public bool HasNonePermit
{
get
{
return ! (CanBrowse || CanAdd || CanUpdate || CanDelete || CanAudit || CanCancelAudit) ;
}
}
#region IPermission 成員
#region CanBrowse
private bool canBrowse = false ;
public bool CanBrowse
{
get
{
return this.canBrowse ;
}
set
{
this.canBrowse = value ;
}
}
#endregion
#region CanAdd
private bool canAdd = false ;
public bool CanAdd
{
get
{
return this.canAdd ;
}
set
{
this.canAdd = value ;
}
}
#endregion
#region CanUpdate
private bool canUpdate = false ;
public bool CanUpdate
{
get
{
return this.canUpdate ;
}
set
{
this.canUpdate = value ;
}
}
#endregion
#region CanDelete
private bool canDelete = false ;
public bool CanDelete
{
get
{
return this.canDelete ;
}
set
{
this.canDelete = value ;
}
}
#endregion
#region CanAudit
private bool canAudit = false ;
public bool CanAudit
{
get
{
return this.canAudit ;
}
set
{
this.canAudit = value ;
}
}
#endregion
#region CanCancelAudit
private bool


#region GeneralPermission
public class GeneralPermission :IPermission
{
public bool HasNonePermit
{
get
{
return ! (CanBrowse || CanAdd || CanUpdate || CanDelete || CanAudit || CanCancelAudit) ;
}
}
#region IPermission 成員
#region CanBrowse
private bool canBrowse = false ;
public bool CanBrowse
{
get
{
return this.canBrowse ;
}
set
{
this.canBrowse = value ;
}
}
#endregion
#region CanAdd
private bool canAdd = false ;
public bool CanAdd
{
get
{
return this.canAdd ;
}
set
{
this.canAdd = value ;
}
}
#endregion
#region CanUpdate
private bool canUpdate = false ;
public bool CanUpdate
{
get
{
return this.canUpdate ;
}
set
{
this.canUpdate = value ;
}
}
#endregion
#region CanDelete
private bool canDelete = false ;
public bool CanDelete
{
get
{
return this.canDelete ;
}
set
{
this.canDelete = value ;
}
}
#endregion
#region CanAudit
private bool canAudit = false ;
public bool CanAudit
{
get
{
return this.canAudit ;
}
set
{
this.canAudit = value ;
}
}
#endregion
#region CanCancelAudit
private bool