VS2005 身分認證與權限控管

身分驗證與權限控管

在系統的開發過程中,通常都會使用身分的驗證以及各種權限的控管機制,雖然Microsoft也提供了Active Directory驗證/Windows驗證,以及Profile個人資料取得的一些機制,但是在一般系統的開發來說,大多數的帳號管理還是透過資料庫來做驗證,而根據登入者身分來區分是否能夠登入系統,或具備何種權限。在這部分我單純使用ASP.NET的程式來控管登入身分以及提供區分跟驗證各種權限的功能。
假設環境:
  1. 帳號密碼存放於資料庫。
  2. 每種登入身分的定義方式不同。
  3. 無法定義登入身分但擁有帳號密碼者不允許登入。
  4. 每一個頁面登入權限不一定相同。
在設計的過程中,我將簡單的實作假設環境的需求,透過Design Pattern的Singleton模型,我設計一個Class名為Authenticate,它將具備static Make Method來負責驗證UserName/Password,並且未來提供static GetAuthenticate Method來取得此物件,此物件將為了存放帳號/權限/個人資料等資訊而存在,這是一個很單純的身分驗證框架,只是透過static的Method方便未來其他的Class要使用的時候可以參考。

public enum IDENTIFY { SYS_ADMIN=0, DEPT_ADMIN=1, USER=2 };
public class Authenticate {
private string _UserName;
private IDENTIFY _Identify; // 權限
private UserInfo _UserInfo; // 登入者個人資料
private Authenticate() {
}
public static Authenticate Make(string userName, string password){
// Check UserName&Password and store an Authenticate class in Session.
}
public static Authenticate GetAuthenticate() {
if (Session["Authenication"] != null) {
return (Authenticate)Session["Authenticate"];
}
return null;
}
第二個問題是每一種身分的定義方式不同,那我就假設每一個身分都存在一種定義方式,因此以範例來說,我就直接在建立三個Method來做判定,分別是isSysAdmin、isDeptAdmin、isUser,如果該處理結果為true,就可以明確建立該身分別的Authenticate放入Session提供Page未來權限控管使用,因此在Make Method中,將會呼叫這幾個Method來檢查是否符合該身分,皆不成立時,則不回傳Authenticate元件,而已null表示登入失敗(第三個項目)。
在擁有身分別之後,每一個頁面必須要提供不同的權限控管時,透過繼承並改寫ASP.NET預設的BasePage,統一將程式碼寫在自訂的CustomBasePage頁面上,但是由於不同Page將會有各自客制化的權限,因此CustomBasePage將開放一個Virtual Method給各Page提供Override權限表,以方便每一個Page分別獨立客制化。在這裡我們不採用VS2005的MasterPage來做統一處理,因為MasterPage的程式碼執行時間晚於該Page的Code,因此每一個Page如果在驗證之前存取資料會造成未知的錯誤發生,因此我們採用改寫BasePage的方式來實作,而每一個Page只要模仿CustomBasePage的GetAuthorityCollection方式來修改,就可以擁有各自的權限控管。

public class CustomBasePage: System.Web.UI.Page {
protected override void OnLoad(EventArgs e) {
if(Authenticate.GetAuthenticate()==null){
Response.Redirect("../Pages/login.aspx");
}
else if(!HasAuthority()){
//很抱歉,您的權限無法使用本功能。
}
else{
//允許登入
}
}
protected virtual DataCollection GetAuthorityCollection() {
DataCollection Collection = new DataCollection();
Collection.Add(
new AuthorityConstraint(
IDENTIFY.ANY,
AuthorityConstraint.DEPT_TYPE.ANY, 
AuthorityConstraint.DATE_TYPE.ANY));
return Collection;
}
protected bool HasAuthoriy() {
DataCollection Collection = GetAuthorityCollection();
foreach (AuthorityConstraint authority in Collection) {
if(authority.HasAuthority()){
return true;
}
}
return false;
}
}

沒有留言:

橫式廣告