我曾經在想,怎麼樣控制權限比較好呢。曾經嘗試過控制到頁面,很方便,但不細致;也曾想過控制到按鈕,很麻煩,也不靈活。最終我決定,還是控制到方法吧(實際是控制到類),所以現在這套權限管理方案便產生了。只需要繼承與一個類,並給它設置一個attribute,就那麼簡單。這就是Lm.Common.Auth命名空間提供的權限控制方案。

 

以下是對這種權限控制方案的簡單描述,以及整理出來的最簡代碼。

 

完整代碼請訪問我的開源項目,HTTP://lmcommon.codeplex.com/

 

OperationBase類,是權限控制的核心。如果一個類ClassA繼承與OperationBase,那麼ClassA提供的所有方法,都將受到OperationBase的權限控制。

 

所謂權限控制的核心,就是判斷一個用戶標識和一個權限標識之間的對應關系。

 

OperationBase類對其子類的以下兩個要求,使得OperationBase類收集到這個兩個標識。

 

1、OperationBase類要求其子類必須向其構造函數提供一個用戶標識;

 

2、OperationBase類要求其子類必須有一個OperationAttribute特性,並在OperationAttribute中提供權限標識。

 

權限控制執行過程(子類以CreateOrder【創建訂單類】為例):

 

1、向CreateOrder類的構造函數傳遞一個用戶標識,以便構造一個CreateOrder類的實例;

 

2、由於CreateOrder繼承與OperationBase,OperationBase的構造函數必然會被調用;

 

3、在OperationBase的構造函數中,檢查CreateOrder是否具有OperationAttribute特性,如果,提取出其中的權限標識,如果沒有,拋出異常,終止構造過程;

 

4、收集到用戶標識和權限標識後,去數據庫中比對,如果此用戶,沒有權限,拋出異常,終止構造過程;

 

5、CreateOrder的實例無法構造,其提供的方法,自然無法執行,以達到權限控制的目的。


2012091810014598  
 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Lm.Common.Auth
{
/// <summary>
/// 權限控制的核心類
/// </summary>
public abstract class OperationBase
{
/// <summary>
/// </summary>
/// <param name="user">用戶編號</param>
protected OperationBase(string user)
{
//獲取子類的權限編號
var attrList = this.GetType().GetCustomAttributes(typeof(OperationAttribute), false);
if (attrList.Length != 1)
{ throw new Exception("當前類" + this.GetType().FullName + "沒有OperationAttribute特性"); }
var attr = (OperationAttribute)attrList.Single();
var operationCode = attr.OperationCode;
//拿到了權限編號,和參數中的用戶編號,
//就可以去數據庫中比較,看看該用戶是不是具有這個權限,
//如果沒有權限,拋出異常,中斷權限實際操作類的構造
}
}
/// <summary>
/// 這個類用來存儲權限編號
/// </summary>
public sealed class OperationAttribute : Attribute
{
public string OperationCode { get; set; }
 
private OperationAttribute()
{ }
public OperationAttribute(string operationCode)
{
this.OperationCode = operationCode;
}
}
/// <summary>
/// 這個類提供創建訂單的功能,這個類的權限編號是「CreateOrder」
/// </summary>
[Operation("CreateOrder")]
public class CreateOrder : OperationBase
{
public CreateOrder(string user)
: base(user)
{ }
public void Work1()
{
//完成某些功能
}
public void Work2()
{
//完成某些功能
}
}
}


From:CNBLOGS        

 
arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()