ASP.NET安全架構--如何實現.NET安全

範大腳腳發表於2017-11-22

      前言:大家是否在用Forms驗證的時候,常常被很多的概念攪混?是否真的明白什麼是Principal,Identity,以及 IPrincipan…?很多的文獻很少提及這些到底是什麼,僅僅是怎麼用,結果出問題,導致很多的朋友的理解僅僅停在表面,使用起來也是束手束腳。相信看完本篇,會有一定的收穫的。

       ASP.NET安全架構為實現Web應用程式的安全模式提供了物件模型。不管我們選擇哪一種的身份驗證模式,其中很多的要素是相同的。登入到應用程式的使用者按照他們提供的憑證被授予Principal和Identity。其中Principal物件表示的是使用者的當前的安全上下文,包括使用者的標識和他們所屬的角色。Identity物件表示的是當前使用者。Principal物件是利用Identity物件(表示使用者的標識)建立的,而且它新增一些額外的資訊,比如角色或者自定義的資料。

簡言之:Principal=Identity+角色+自定義資料

大家要注意一點:身份驗證是發生在ASP.NET執行的特定的時期的,記住這一點,具體的以後會講的。 下面我們具體的談:

一 表示安全的上下文 

       Identity物件表示的是通過身份驗證的使用者。Identity物件的型別取決於所使用的身份驗證,如,Windows身份驗證使用的是 WindowsIdentity物件,而Froms驗證使用的是FormsIdentity物件。

       大家開始接觸Identity概念有點難受,其實說白了Identity就是一個使用者的標識,標識是什麼?就是標明使用者是什麼,使用者名稱字是什麼而已,只是我們這裡說的比較專業一點點而已。 

       另外,Principal物件表示的是通過身份驗證的使用者的組或者角色的成員:也就當前使用者安全上下文。說安全上下文,說白點就是這個物件包含很多的使用者身份的一些資訊。Principal物件是有IIS中的Windows 身份驗證自動的建立的,但是我們也可以建立普通的Principal物件(大家後面就慢慢明白的). 

       大家在程式設計的時候,或多或少用過HttpContent.Currrent.User屬性,其實它表示的就是一個Principal物件.Principal物件是實現了IPrincipal介面的。 

  IPrincipal 介面 

       不同的身份驗證模式對安全的上下文有不同的要求。我們可以利用Principal物件表示當前的安全上下文。 IPrincipal介面定義了Principal物件的基本功能。而且我們還可以自定義安全的上下文物件,只要實現 System.Security.Principal介面:

Identity屬性--可以獲取當前Principal物件的Identity.之前說過:Principal包含Identity就是這個原因。 

IsInRole(string roleName)方法--可以判斷當前的Principal物件是否屬於指定的角色。大家在變成時候也用過類似的HttpContent.Current.User.Identity.IsInRole(“Admin”)語句。 

       Principal物件可以通過HttpContent.Current.User屬性訪問到,下面的程式碼大家應該都用過的:

if(HttpContext.Current.User.Identity.IsAuthenticated) 



  lblUserName.Text=HttpContext.Current.User.Identity.Name+”已經登入”; 

}

(注:Identity是使用者的標識,包含使用者名稱。我們後面會講的)

      下面的程式碼就更加的常見了:判斷當前的使用者是否是管理員角色

if(HttpContext.Current.User.IsInRole(“Admin”) 



// 

}

       接著我們就看看ASP.NET內建的實現了IPrincipal介面的物件: 

GenericPrincipal類 

       GenericPrincipal類實現了IPrincipal介面。從名字可以看出GenericPrincipal物件表示的是一個一般的,基礎的安全上下文,它僅僅只是定義了當前使用者的角色,也就是說這個物件只是部分的實現了IPrincipal介面。(以後我們就把實現 IPrincipal介面的物件稱為 主體)。對於一種身份驗證模式來講,如 Windows身份驗證,它使用的就是WindowsPrincipal,因為WindowsPrincipal更加具體的實現了IPrincipal。而在Forms驗證中,用的只是一般的GenericPrincipal。也就是說,我們可以按照我們的要求實現自定義的Principal物件。下面會講到的。 

       IPrincipal介面的每一個實現都要重寫Identity屬性和IsInRole方法。GenericPrincipal類的 IsInRole方法是通過把角色值和在字串在中定義的角色進行比較,而WindowsPrincipal類的IsInRole方法則是把角色和被分配到Windows使用者帳戶角色進行比較。

       我們可以建立一個在當前請求的整個生命週期中都要使用的GenericPrincipal類的例項,並把它賦值給HttpContent.Current.User屬性。 

GenericPrincipal的建構函式有兩個引數:使用者的GenericIdentity(使用者標識GenericIdentity實現了 IIdentity介面),和一個表示使用者角色的字串陣列。所以我們之前說:Principal=Identity+角色就是這原因。 

       GenericPrincipal 物件一旦被建立,就可以賦值到HttpContent.Current.User屬性,用來表示當前請求使用者的安全的上下文。 

       下面就是建立的程式碼例子:

 

//建立一般的GenericPrincipal 

//我們說過:標識就是包含使用者名稱的物件,如下 包含一個名為”xiaoyang”的標識 

GenericIdentity identity=new GenericIdentity(“xiaoyang”); 

//建立GenericPrincipal 

//注roles表示的是一個角色的字串陣列如role=new string{“Admin”,”Customer”}; 

GenericPrincipal principal=new GenericPrincipal(identity,roles); 

//附加 

HttpContext.Current.User=principal;

 

  注意:上面的程式碼是要寫在特定的地方,也就是生命週期的特定的時候的,我們後面講述。 

       說了Principal,下面就說說使用者標識到底是什麼,之前多次提到的。 

二 使用者標識 

   Identity物件用於標識當前使用者的標識。標識只能提供少量的安全上下文資訊,如使用者名稱。Identity物件可以驗證使用者。 

      IIdentity介面 

       和IPrincipal介面一樣,表示使用者標識的物件都要實現這個介面。IIdentity介面定義了Identity物件的基本額的結構,定義如下:

AuthenticationType(string型別的)屬性–它可以獲取所使用的身份驗證的型別,如,如果使用的Forms驗證,該屬性返回”Forms”字串,所以我們自定義的標識可以返回”CustomIdentity”字串。 

      IsAuthenticated(bool型別)屬性–標識使用者是否通過身份驗證。我們可以常常用HttpContext.Current.User.Identity.IsAuthenticated來判斷使用者是否已經登入。 

Name(string 型別的)屬性–獲取使用者的名字。相信對HttpContext.Current.User.Identity.Name不陌生。

       下面我們就看看我們自己的實現了IIdentity介面的標識類。

 

using System; 

using System.Security.Principal; 

public class CustomIdentity : IIdentity 



private string name; 

//建構函式只接收一個string引數,大家可以看看之前我們程式碼:GenericIdentity identity=new GenericIdentity(“xiaoyang”); 

public CustomIdentity(string name) 

        { 

this.name = name; 

        } 

// 

private string authenticateType = “CustomerIdentity”; 

public CustomIdentity(string name,string authenticateType) 

        { 

this.name = name; 

this.authenticateType = authenticateType; 

        } 

//下面就實現介面 

private bool isAuthenticated = false; 

public bool IsAuthenticated 

        { 

get { return isAuthenticated; } 

        } 

private string name; 

public string Name 

        { 

get { return name; } 

        } 

}

 

      上面的程式碼只是示範,大家可以按照自己的要求擴充套件。 

       和之前一樣,我們來看看ASP.NET中內建的Identity類: 

  FormsIdentity--在Forms驗證中使用 

       PasswordIdentity--在Passport驗證中使用 

       GenericIdentity--一般的普通的標識 

       WindowsIdentity--Windows 身份驗證使用 

       我們來看看GenericIdentity的使用,其他的使用類推。

       其實GenericIdentity標識的是一個基本的Identity 物件。它對於Identity物件來說是做基本的。之前我們看過一個GenericPrincipal的例子,在那個例項中我們建立一個GenericIdentity類的例項,

 

GenericIdentity identity=new GenericIdentity(“xiaoyang”);

      而且我們還可以提供更加具體的Identity物件,如之前提到的FormsIdentity,開提供具體的使用者資訊。 

       今天就到這裡,希望大家有收穫。

本文轉自today4king部落格園部落格,原文連結:http://www.cnblogs.com/jinzhao/archive/2009/05/02/1447909.html,如需轉載請自行聯絡原作者


相關文章