天天看點

ASP.NET安全問題--ASP.NET安全架構

在開發Web程式中,我們可以選擇用自己的方法來實作安全的政策,或者可以購買第三方的安全代碼和産品,不管怎麼樣,都是要很大的花費的,幸好在.NET Framework中已經内置了安全的解決方案。        ASP.NET和 .NET Framework 聯合IIS為Web應用程式安全提供了一個基礎結構。它的一個很明顯的優勢在于我們不必再編寫自己的安全架構,我們可以利用.NET安全架構的内置的特性,而且整個安全的架構是經過測試和時間的考驗了的。

       .NET安全架構包含了很多的類,這些類用來處理身份驗證,授權,基于角色的授權,假冒(Impersonation),代碼通路安全,還包含了一個用于建構自定義解決方案的基本架構。

       下面就開始:

       一 ASP.NET實作安全的過程 

    ASP.NET 安全架構分為幾個關鍵的安全過程:身份驗證,授權,假冒,加密提供提供了必需的功能。具體看看一些解釋:

       身份驗證--指明是誰再通路我們的站點

       授權----誰可以對哪些資源操作和通路?通路站點的使用者是否被授權使用他所請求的資源?

       假冒----準備假冒什麼角色?(注:假冒不是貶義詞,不是我們常說的假冒商品的假冒,因為不同的使用者角色有不同的權限,如果  我們目前的使用者無法通路某一特定的資源,我們就可以讓想通路特定資源的使用者假冒,更确切的說是模仿有權限通路特定資源的使用者,簡言之:使用者A想通路C資源,但是沒有權限,但是使用者B可以通路,是以A和B商量,A就用B的身份通路。具體的以後講解)

       下面我們具體看看每個安全的過程:

       1.身份驗證

       身份驗證是揭示使用者辨別(注:辨別的概念我們後面馬上就講的,簡言之,使用者的ID 和 名稱)并判斷辨別真實性的過程。很好了解,舉個例子(大家注意例子中的一些術語):我們要取參加一個會議,我們就會取登記提供我們的一些證件即辨別(表明我們的身份),一旦辨別被确認,我們就會得到會議通行證,我們就可以帶着通行證參加會議。而且會議中的每個人都可以通過我們的通行證了解我們的一些資訊,如我們的名字,公司。身份驗證就是:一旦辨別被确定,我們就會得到一個可以識别我們的令牌,是以,再一個特定的區域内,不管我們在哪裡,我們的辨別都可以被識别。

       在ASP.NET中,有4中身份驗證的模式:

       Widows身份驗證(Windows Authentication)

       Forms身份驗證(Form Authentication)

       Passpot身份驗證(Passport Authentication)

       自定義身份驗證

       對于每一種身份驗證,使用者都需要在登入的時候提供憑證,一旦辨別被核實,使用者就會獲得一個身份驗證令牌,在Forms驗證中,整個令牌就是FormsAuthenticationTicket,整個令牌就放在 cookie中,每次請求資源的時候,令牌就會提供使用者的辨別資訊。

       2.授權

       我們接着拿之前的那個會議的例子來看,授權就是表明我們可以做什麼。進入會議廳以後,發現有很多不同的會議,專家級的,普通級的,不同人參加不同級别的會議。而且有些人可以參觀整個會議廳,但是有些人隻能在展覽廳參觀。這就是權限的不同而導緻的。

       是以,授權就是:以我們的辨別資訊為參考,準許或者拒絕通路我們請求的資源。還有一點要注意的是:我們一般是常用的是基于角色的授權,就是把使用者分為一組一組,然後給每組不同的角色。

       假冒

       假冒是在其他使用者辨別的上下文中執行代碼的過程。在預設情況下,所有的ASP.NET代碼都是在Domain/ASPNET使用者賬戶下執行的,要利用其他的辨別執行代碼,假冒其他的辨別,我們應該利用.NET安全架構中的内置的假冒的功能。它允許我們指定執行代碼的使用者賬戶,比如不同于Domain/ASPNET的預定使用者賬戶。我們既可以利用ASP.NET中身份驗證功能來驗證使用者,也可以利用标準的Windows身份驗證來驗證使用者。

      然後我們可以利用我們的憑證,或者利用執行代碼的預定義使用者賬戶來設定所假冒的賬戶。

       假冒還允許我們在不使用ASP.NET提供的身份驗證和授權功能的情況下提供身份驗證和授權:我們可以利用使用者賬戶和他們相關權限支援Windows和IIS管理身份驗證和授權。

       假冒通常用于提供通路控制,比如授權,一個應用程式可以通路它所假冒的的使用者可以通路的任何資源。例如,預設情況下,Domain/ASPNET使用者不能對檔案系統進行讀寫操作的,是以這個使用者賬戶也無法在Enterprise Services中執行事務處理。但是利用假冒,使用者就可以通過假冒一個特定的Windows賬戶完成這些事情,因為這個特定的賬戶有這個權限。是以,我們就可以保證一些使用者可以對檔案系統進行讀寫操作,而其他的一些使用者僅僅執行讀的操作。

       好了,上面講了很多,我們現在就來小結一下,看看如何把身份驗證,授權,假冒一起用于Web程式中。

       當使用者首次通路Web站點時,他們是匿名使用者,我們不知道他們的辨別,除非對他們進行身份驗證,否則我們以後還是不知道他們的辨別。當使用者請求非安全的資源時,他們可以自動的通路這個資源(這就是非安全資源的定義)

       當使用者請求安全的受保護的資源時,就要如下步驟:

       1.請求被發送到 Web伺服器,由于此時這個使用者辨別還有被确認,是以使用者就被重定向到登入頁面

       2.使用者提供憑證,身份驗證就對憑證進行驗證和稽核

       3.如果使用者憑證合法,就可以通路資源,否則,就不能。

       當使用者請求安全的資源,但是該資源有特定權限的使用者才能通路,就會發生下面步驟:

       1.請求被發送到 Web伺服器,由于此時這個使用者辨別還有被确認,是以使用者就被重定向到登入頁面

       2.使用者提供憑證,身份驗證就對憑證進行驗證和稽核

       3.把使用者的憑證或者角色與被允許的使用者或者角色進行比較,如果使用者在清單中,那麼他們就被準許通路這個資源,否則,拒絕。

       如果啟用了假冒,那麼在這兩種情況下,假冒都會發生。預設情況下,假冒是禁止的,可以修改配置檔案添加<identity>元素啟用:

 <configuration><system.web>

   <identity impersonate="true" userName="Xiaoyang/User" password="xiaoyang"/>

  </system.web> </configuration>

       在<identity>中,把impersonate特性設定為true,拿userName和 password設為要假冒的使用者賬戶。 如果假冒被啟用,那麼被稽核的就是假冒的使用者辨別的憑證,而不是送出的憑證。這兩種憑證有可能相同,需要注意的是:假冒是利用Web伺服器中已有的使用者通路,如IUser使用者。

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

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,開提供具體的使用者資訊。

ASP.NET生命周期中的驗證以及身份驗證子產品

       其實在ASP.NET中每一個請求都進行了驗證和授權的。進行驗證和授權的過程實際上是通過觸發相應的事件來完成的。

       在講述驗證事件之前,首先清晰一個流程:ASP.NET運作時接到一個請求的處理的流程。

       先把流程描述一下,使得大家有個總體把握:一個請求來了,經過IIS,通過ISAPI,就到達了ASP.NET的管道中,然後經過一些的轉化和包裝,然後ASP.NET運作時開始處理這個請求了,然後是進行驗證和授權,然後再進行一系列的處理,最後确定請求是是什麼檔案,如果是.aspx的,那麼然後就開始頁面的生命周期,如下圖。

      下面就處理請求時候觸發的事件順序如下:

       BeginRequest: 開發處理請求,是處理ASP.NET請求時觸發的第一個事件 

       AuthenticateRequest:處理身份驗證

       ...

       AuthorizeRequest:處理授權

       ...

       是以大家可以看出,其實在請求的處理過程中,身份的驗證和授權發生的時期是很早的。而且有關驗證的一些資訊,如使用者名和角色在處理完這兩個事件之後就已經确定,并且填充。下面我想用個圖來講述:

      一般對于請求的驗證和授權,我們是希望也應該自己控制這個過程的,是以我們可以在AuthenticateRequest和AuthorizeRequest的事件進行中加入我們自己的代碼。一般在網站中加入 Global.asax檔案。

       AuthenticateRequest事件:

       當一個請求需要進行身份驗證時,HttpApplication對象就會觸發AuthenticateRequest事件,這也意味着每次對ASP.NET應用程式進行頁面請求時都會觸發這個事件。

       在這個事件中實際上是調用相應的身份驗證子產品來處理身份驗證的。例如對于Forms身份驗證子產品而言,就是從加密的cookie中提取使用者資訊。

       AuthorizeRequest事件:

       AuthorizeRequest事件是在AuthenticateRequest事件中通過了身份驗證時候才觸發的。AuthorizeRequest事件調用相應的授權子產品來檢查使用者是否被授權通路他們請求的資源。因為在AuthenticateRequest事件完成之後就已經有了使用者的表示Identity和IPricipal,也就知道了使用者名和角色的資訊。

       2.身份驗證子產品

       身份驗證是利用ASP.NET中的身份驗證子產品來實作的。在ASP.NET中内置有四個驗證子產品:

      DefaultAuthenticateModule,FormsAuthenticateModule,WindowsAuthenticateModule,PassportAuthenticateModule.他們都實作了IHttpModule接口,當然,如果需要,我們也可以實作自定義的驗證子產品。

      從驗證子產品就可以看出我們一般的身份驗證是怎麼進行的,決定采用個驗證子產品是由我們決定采用哪種身份驗證決定的,如Forms驗證就是用了FormsAuthenticateModule來處理的。而且還要配置web.config檔案

中的<authentication/>元素。

       下面我們就先來看看身份驗證子產品的實作(僞碼)

 public class FormsAuthenticationModule:IHttpModule 

{

   #region IHttpModule 成員

        public void Dispose(){ throw new NotImplementedException();}

        public void Init(HttpApplication context)  {

         context.AuthenticateRequest += new EventHandler(context_AuthenticateRequest);

        }

  public event FormsAuthenticationEventHandler Authenticate;

        #endregion

}

       大家可以看到,其實在子產品的Init方法中就訂閱了AuthenticateRequest事件,而我們在Global.asax中寫的代碼就是我們具體處理的代碼:

 void context_AuthenticateRequest(object sender, EventArgs e){

                //自定義驗證代碼

        }

       還有一點要注意的就是:每個子產品都有一個Authenticate事件。

       下面就說說常用的兩個個驗證子產品,因為大同小異:

       WindowsAuthenticateModule:

       WindowsAuthenticateModule是和IIS身份驗證聯合試用的,當web.config 的中配置如下:

       <authentication mode="Windows"/>

       此時,這個子產品就激活了,在Global.asax檔案中就的Application_Authenticate(object sender,eventArgs e)就是給Windows驗證用的。

      這裡有一個問題要澄清:如果是我們配置的是Windows身份驗證,我們在Application_Authenticate中就隻能寫和Windows身份驗證有關的代碼,如果是配置的是Forms驗證,我們在Application_Authenticate就隻能寫和Forms有關的代碼,如擷取cookie資訊等。也就是說,Application_Authenticate方法是"一法多用"。

       接着談 Windows驗證,在上面的處理程式中,我們可以建立自己的使用者資訊,如我們建立一個WindowsPrincipal類的執行個體(實作了IPrincipal接口,包含使用者名和角色的資訊),然後它指派給 HttpContext.User屬性。這正如我們之前說的,驗證事件執行完之後,我們就知道了這個請求的發起者的使用者名和角色資訊。

       FormsAuthenticateModule:

       首先還是要配置:<authentication mode="Forms"/>.

       FormsAuthenticateModule可以利用cookie解析儲存在cookie中的使用者的資訊,并且建立一個GenericPrincipal,把使用者名和角色資訊儲存在其中,然後指派給User屬性,以備後用。

       3.授權子產品

       在ASP.NET中内置的授權子產品主要有兩個:FileAuthorizationModule和UrlAuthorizationModule。他們也實作了IHttpModule接口。這些子產品可以參照所試用的身份驗證類型來決定到底采用哪個授權子產品:

       如果試用的是Windows身份驗證,那麼在授權檢查的時候就會使用FileAuthorizationModule;

       如果在web.config中提供了<authorization/>元素,那麼就會采用UrlAuthorizationModule。如下面的:

<authorization><allow roles ="" users=""/><deny users=""/></authorization>

       FileAuthorizationModule:

       如果使用 Windows身份驗證,就會采用FileAuthorizationModule子產品。這個子產品可以處理Authorization事件,并且能夠對IIS提供的請求的令牌和目标資源執行通路檢查。而且這也用到了系統的ACL(通路控制清單).

      例 如,如果請求的資源是Default.aspx,目前的使用者是xiaoyang,那麼FileAuthorizationModule就會執行通路檢查,看看xiaoyang時候具備通路Default.aspx的讀的權限,如果在Windows的使用者賬戶中有xiaoyang這個賬戶,并且具有通路的權限,那麼請求成功,否則,FileAuthorizationModule就把Reponse.StatusCode設定為401(未授權),之後請求就結束了。

       UrlAuthorizationModule:

       和上面的處理子產品不一樣,不管使用何種類型的身份驗證,隻要配置了web.config中的<authorization/>元素,就要使用UrlAuthorizationModule子產品。這個子產品在處理的時候執行如下:

       1,把<authorization/>中聲明的使用者名和HttpContext.User.Identity進行比較

       2.把<authorization/>聲明的角色資訊和HttpContext.User.IsInRole比較

       如果比較成功就可以通路相應的授權的資源,否則把Reponse.StatusCode設定為401(未授權),之後請求就結束了。

ASP.NET安全問題--Forms驗證的具體介紹(上篇)

1.基于角色的安全

       相信大家多什麼是角色的,以及基于角色的安全都有一些了解,他們的概念就不贅述了。在講述基于角色的安全之前,希望大家對之前講過的Identity和IPrincipal要了解(如果不是很清楚的,可以參看我之前的安全的系列文章)。

       在.NET中,可以用.NET Framework靈活的将使用者辨別(Identity)和角色相結合,并且為結合後的主體定義權限。我們之前說過:

       主體(IPrincipal)=(使用者辨別:包含使用者名等資訊的對象)Identity+角色;

       我們可以定義很多的角色,然後為角色定義通路資源的權限。我們一般是定義角色,如定義一個Customer角色,然後使使用者的角色為Customer,然後我們定義Customer的通路權限,那麼這些通路的權限就應用到了那些角色為Customer的使用者上,也就是說,我們并不是為每個使用者分别定義權限,因為那樣維護和修改起來麻煩。

       當然,我們也可以對特定的使用者單獨的進行授權,如寫入檔案。授權的方式很多,但是他們的思想是大體相同的:

        通常,一個應用程式的授權步驟如下:

       1.判斷使用者是否有合法的通路資源的憑證(也就是我們之前談論的驗證的過程)

       2.拒絕特定的使用者通路特定的資源

       3.允許特定的使用者通路特定的資源

       2. 權限的映射:

       在.NET 中,有一些内置的Permission對象,它們可以使得使用者有合适的權限來通路資源。在講後面的問題之前,首先說說什麼是Permission。我們知道,我們的系統中一般有很多的檔案和檔案夾,而且這些檔案或者檔案夾常常都是有通路的權限的,比如,我們可以把一些檔案的權限定義為:隻能管理者修改,一般的使用者隻讀,這點大家都不陌生了。

       注意:我們是通過系統來配置這些檔案或者檔案夾的權限的。(大家應該都會)

       我們的網站,實質其實就是放在伺服器上的一些檔案,既然這些檔案在伺服器,如Win Server 2003上,那麼這些檔案肯定是有通路的權限的。如果你是這台伺服器的管理者,那麼你就可以對這些檔案進行任意的操作,其他的使用者就沒有這個能力了。

       現在我們假設,我們的網站是放在伺服器上,而且網站的檔案,如aspx頁面,圖檔,App_Code等都在網站的檔案夾中,而且這些檔案資源的權限早就定義好了,如隻讀。

       其實我們在.NET中的一些Permission類,其實就是權限的映射。怎麼說?

       假如我們的網站檔案夾中的一個檔案,如Admin.aspx頁面,我們可以通過作業系統來定義這個檔案的通路權限(操作為:選中檔案,點選右鍵,選擇"共享和安全",然後選擇哪些使用者可以通路,而且這些使用者的操作是什麼,如讀,寫,安全控制等)。這些都是系統定義的一些權限,.NET Framework就把定義在檔案上的一些權限"取出",包裝映射在一些Permission類中,這樣我們就能用托管代碼,如C#來操作這些權限,而不用Win API(非托管代碼)來操作。(了解如有問題,歡迎大家指正!)

        3.權限對象Permission簡介

       下面我們就舉一些Permission類的例子.

       FileIOPermission

       PrincipalPermission

       這些内置的權限對象都會保護指定的資源。如FileIOPermission對象将確定隻允許授權的使用者通路一個檔案。即,FileIOPermission對象将目前使用者的憑證映射在作業系統級别,映射的結果就是該使用者和系統中已存在的某一使用者的操作權限相同(如IUser),那麼現在這個使用者就可以設定檔案的權限。

      FileIOPermission

      FileIOPermission對象要求使用者是Windows使用者,或者ASP.NET處理過程運作在一個特定的辨別下(一般是ASPNET使用者賬戶),并且根據為檔案系統中的檔案或者檔案夾定義的權限,授予讀或者寫的權限。即,FileIOPermission對象在檔案系統中定義的權限上下文中驗證Principal.

       例如,在ASP.NET程式中,我們可能想要在點選按鈕之後寫入一個檔案,那麼,檔案就應該配置必需的通路權限,并且為登入到應用程式的使用者授予必需的權限。

       如果想要拒絕通路一個特定的檔案夾,如C:\Windows,那麼我們就可以通過在運作階段拒絕對FileIOPermission對象操作的權限來實作。我們就可以在特定的地方寫下:

[FileIOPermissionAttribute("SecurityAction.Deny,All="C:\\Windows")]

       上面是以聲明的方式寫的,我們也可以用代碼,以後講述。

       其中SecurityAction枚舉定義了通路的類型,如拒絕Deny。

       上面的聲明可以在類級别,方法級别,以及程式集級别使用。這裡隻是簡單的描述,大家知道就行了,具體的我們後面講述。

       PrincipalPermission

     PrincipalPermission確定調用者的上下文具有與之相關聯的被請求的Principal。這話有點繞,下面看個例子就明白了:

       下面的代碼確定:隻運作名為"xiaoyang"的使用者通路一個特定的方法:

 [PrincipalPermission(SecurityAction.Demand,Name="localhost\\xiaoyang"]

 ASP.NET安全問題--Froms驗證的具體介紹(上篇)

       我們知道,Forms驗證主要是基于cookie的,說白一點就是:把使用者資訊儲存在cookie中,然後發送到用戶端;再就是解析用戶端的發送了的cookie資訊,進行解析,然後進行驗證。關于cookieless的工作原理和方法,我這裡不贅述,大家可以參看我的另外的一片文章:淺談ASP.NET内部機制(一)。

       當匿名使用者請求一個需要驗證後才能通路的資源和頁面的時候,那麼如果采用了Forms驗證,那麼URL授權子產品就會把使用者重定向到登入頁面。而之前請求的URL就會被儲存起來,等到使用者正确的登入後,就再次轉向之前要請求的頁面。我想這點,大家應該都用過。

       下面我們就看看登入的時候發生了什麼,看看登入的具體的流程?也請大家注意我使用的一些術語,因為這些術語再Forms中都有特定的對象,大家之後就可以看到的,很重要。

       1.再浏覽器中有個登入窗體,要輸入使用者名和密碼等憑證,通過送出給伺服器的ASP.NET網站來稽核,檢查憑證是否正确。

       2.如果憑證正确,那麼就會再伺服器端就會建立一個"身份驗證票據"。身份驗證票據中含有了經過加密的使用者資訊。

       3.這個票據再伺服器端被寫入cookie中,然後發送到用戶端。

       4.然後使用者就被重定向到他們最初請求的URL中。

       注:大家可能會有疑問:最初請求的URL到底儲存在哪裡?不要擔心,現在隻要明白上面的流程就OK。

        5.上面第4步就是要轉向最初請求的URL,假設最初的請求頁面是Default.aspx,那麼現在就是從登入的頁面Login.aspx轉向到Default.aspx 頁面,此時因為身份驗證的票據cookie已經存在于用戶端的浏覽器中了,此時的轉向Default.aspx頁面時,實際是再次向伺服器端發起了請求,是以正如我們之前所談到的:每個請求都要從ASP.NET管道中一級級的向後傳,要經曆ASP.NET的的生命周期:Application_BeginRequest,Application_AuthenticateRequest.....。(希望大家明白)

       但是這次的請求就和第一次我們發起的請求步同了,為什麼?

       第一次我們請求Default.aspx頁面的時候,我們根本就沒有提供任何的表明我們身份的票據,但是這次我們已經登入了,而且我們的浏覽器中已經有了我們的身份驗證的票據的cookie,此時在Application_AuthenticateRequest事件中,Forms驗證子產品就擷取表明我們身份cookie,然後就利用cookie中資訊填充Context.User。

       驗證子產品處理完之後就是授權子產品起作用了。其實URL授權子產品就會利用我們之前填充在Context.User中的資訊來驗證使用者是否被準許通路所請求的資源或者頁面。

       Forms驗證中的API

       實作Forms身份驗證之前,我們看看組成Forms驗證的API以及相關的類:

       FormsAuthenticationModule:對每個請求進行驗證的HTTP子產品

       FormsAuthentication:包含在Forms驗證中我們常用的方法和屬性(很重要的)

       FormsIdentity:Forms驗證辨別。

       FormsAuthenticationTicket:身份驗證的票據,對使用者的資訊進行加密後的産物,我們一般把它寫如cookie中,之前我們談過了的。

       上面的類在System.Web.Security下。

       下面我們來一一介紹.

       FormsAuthenticationModule

       它是一個實作了IHttpModule接口的類。它可以用來處理每個請求的Application_AuthenticateRequest事件。如果發送了的請求中已經包含了cookie資訊,那麼這個子產品就對cookie資訊進行解密和解析,然後構造一個GenericPrincipal的類執行個體填充Context.User,并且也建立一個FormsIdentity的執行個體。

       注意:當我們在web.config中配置了Forms驗證後,那麼我們在Application_AuthenticateRequest事件寫的代碼要是和Forms相關的API。上篇文章談過了。

        FormsAuthentication類

       這個類很重要。

       還有一點注意的就是:因為FormsAuthentication和FormsAuthenticationModule名稱很相似,很容易混淆。

      它們之前的差別在于,FormsAuthenticationModule是一個HTTP子產品;而FormsAuthenticate是一個類,它有很多的方法和屬性。更加直白的說就是:它們之前沒有什麼關聯,隻是在Application_AuthenticateRequest事件中我們常常要調用FormsAuthenticate類的一些方法和屬性。而且FormsAuthenticate的很多方法都是靜态的方法,我們不會建立FormsAuthenticate類的執行個體。

       還有一點要特别注意的就是FormsAuthenticate的Authenticate方法。

       我們之前說過了,我們一般是在登入窗體中送出使用者資訊,然後伺服器端驗證送出的資訊,我們在伺服器端常常是去資料庫中檢查這些資訊的正确性,但是去資料庫或者其他的資料存儲(如檔案,活動目錄)中去檢查隻是一種情況。

       還有另外的情況。不知道大家是否記得web.config 中的一個配置的節點:

 <authentication mode="Forms">

        <forms>

          <credentials>

            <user name="xiaoyang" password="xiaoyang"/>

            <user name="panyan" password="panyan"/>

          </credentials>

        </forms>

     </authentication>

       如果我們在配置檔案配置了上述的資訊,那麼我們就可以用Authenticate方法來檢查提供了使用者資訊(使用者名和密碼)是否正确,如果我們沒有在web.config配置使用者的資訊,也就是說我們是把資訊儲存在資料庫等其他的地方,那麼我們就不能Authenticate這個方法。當然我們很少用Authenticate這個方法,因為我們不可能把所有使用者資訊寫死到配置檔案中,但是還是要清楚這個方法。

       另外我簡單的介紹一些常用的方法,具體的使用我以後會講述。

       在FormsAuthenticate中使用頻繁的是RedirectFromLoginPage方法。每當驗證了使用者的憑證後就會使用到這個方法,也就是我們之前說過的:跳轉到我們最初請求的頁面。

       這個方法就這麼簡單的一"跳",但是其實在内部做了很多的事情:

       1.為使用者建立一個身份驗證的票據

       2.對身份驗證的票據進行加密

       3.建立一個cookie,把加密的票據儲存在cookie中

       4.向HTTP響應添加cookie,并且發送給用戶端。

       5.跳轉,并且把使用者重定向到最初請求的頁面

       另外FormsAuthenticate類還有很多的其他方法和屬性:

       FormsAuthenticate中涉及到用戶端儲存cookie的兩個屬性就是:

       FormsCookieName:擷取或者設設定cookie的名稱

       FormsCookiePath:擷取或者設定cookie的url路徑

       其中FormsCookiePath屬性有一點要注意:大多數的浏覽器會在判斷cookie是否要和請求一起發送時,用到cookie路徑。(我們一般在配置檔案配置path="/"),如果我們配置的path不是"/",那麼這個cookie就不會和請求發送到伺服器端.

       FormsAuthenticate中和cookie操作相關的方法有:

       Decrypt:提取身份驗證cookie的加密資訊,建立FormsAuthenticationTicket,也就是解密。

       Encrypt:加密。從FormsAuthenticationTicket中擷取資訊,并且加密。以備我們之後把加密的資訊寫入cookie

       GetAuthCookie:建立身份驗證cookie,但是并不把它立即添加到HTTP響應中

       SetAuthCookie:建立身份驗證cookie,并且把它添加到Response.Cookie中。

       RenewTicketIfOld:重新整理身份驗證cookie的生命周期

       GetRedirectUrl:把使用者重定向到他們最初請求的頁面。

       SignOut:使得目前的身份驗證cookie過期。我們常用的登出功能。

       FormsIdentity

       大家現在應該知道什麼是辨別 Identity,它包含了使用者名和ID辨別資訊,可以參看我前面的文章。

       FormsAuthenticationTicket 票據

       通過上面的講解,大家已經對它不陌生了,FormsAuthenticationTicket實際上就包含使用者資訊的一個類的執行個體。

       注意:FormsAuthenticationTicket和cookie之間的差別:

       cookie其實就是一個載體,容器,它包含了加密後的FormsAuthenticationTicket。

       FormsAuthenticationTicket類的UserName屬性就是使用者的使用者名,我們可以根據這個屬性識别不同的使用者。

       由于身份驗證是基于cookie的,是以要考慮到cookie的過期的問題。比如我們在登入時有個"記住我"的checkbox,如果勾上,那麼就建立了一個永不過期的cookie,處于安全,我不提倡這樣。

       是以在FormsAuthenticationTicket也提供了關于設定cookie屬性:

       Expiration:擷取一個表示cookie期滿的DateTime對象

       Expired:判斷cookie是否過期

       IsPersistent:是否在使用者關閉浏覽器後繼續儲存cookie

       IssueDate:傳回最初設定cookie的時間

       還有就是CookiePath:設定cookie的儲存路徑,前面談論過了,一般設定為"/"。

       另外FormsAuthenticationTicket身份驗證票據目的是識别使用者。同時,我們也可以利用FormsAuthenticationTicket的UserData屬性添加額外的資訊,如角色等,然後這額外的資訊就可以儲存在cookie中。

       今天就談這裡。大家先有個總體的認識,具體的代碼部分,我們後面談。謝謝各位!!!

ASP.NET安全問題--Froms驗證的具體介紹(中篇)

 啟用Forms身份驗證

       相信大家對很清楚如何啟用 Forms驗證,但是這裡我還是羅嗦一下。

       我們隻要在 web.config檔案中配置如下就行了:<authentication mode="Forms"/>

        這樣之後,ASP.NET運作時就知道我們啟用了Forms驗證,在生命周期的驗證階段就激活FormsAuthenticationModule子產品。

       還有一點要特别注意:<authentication/>元素節點隻能在應用程式的根檔案夾中的 web.config中配置。如果在子檔案夾中使用這個節點就會報錯。這也說明了每個應用程式隻能定義一個身份驗證類型。

       而且在<authentication/>節點中,我們還可以進行更多的設定。如下:

<authentication mode="Forms ">

       <forms name="MyCookie"  loginUrl="Login.aspx" timeout="60"

              path="/"  protection="All">            

       </forms>

 </authentication>

      我們下面就看看<forms>節點中的屬性的含義和用途:

       name:定義身份驗證cookie的名稱。因為我們把身份驗證的票據是存放在cookie中的,而且我們必須給身份驗證cookie取具有唯一性的名稱,防止和其他的應用程式中的cookie沖突。

       loginUrl:從英文名字就可以知道是關于登入的。實際上就是标明把使用者重定向到哪個頁面取登入。

       timeout:設定身份驗證cookie持續的時間,以分鐘為機關的。而且這個時間是一個相對的時間,就是說每次對使用者進行驗證時,cookie的期限就會被重新設定。如果在60分鐘内使用者再沒有向伺服器發起請求,那麼cookie就過期,之後如果使用者再次發起請求,那麼就要重新輸入使用者名和密碼等資訊。

       path:設定cookie的儲存的路徑,一般是設定為"/",我們不要輕易的改變。

       我們之前也說過,我們的身份驗證的票據是加密以後再存放如cookie中的,然後再把cookie發送到用戶端。當用戶端再次請求的時候,再伺服器端就會解析用戶端發送來的cookie資訊,我們必須要确認:用戶端發送來的cookie資訊就是我們之前從伺服器端發送過去的,也就是說,我們要判斷,我們的cookie在用戶端是否被篡改了。

       是以,這就是<forms/>中屬性protection的用途。protection的值有四個:

       Encryption:對cookie的内容資訊進行加密。

       Validation:向cookie中的内容添加MAC(消息驗證代碼),以便伺服器判斷cookie是否被篡改了。

       None:禁用加密和篡改檢查

       All:同時啟用加密和篡改檢查。

       預設情況下是"All",因為它可以把資料加密放入cookie中,而且對傳回到伺服器端的cookie進行驗證。

       使用者資訊的存儲

       我們一般把使用者的資訊,如使用者名和密碼存放在資料庫中。如之前一篇文章說的,我們也可以把使用者的使用者名和密碼資訊直接放在web.config檔案中。

       Forms驗證其實對把使用者憑證資訊放在哪裡提供了很大的靈活性。預設情況下是放在web.config中的。如下代碼:

<authentication mode="Forms ">

       <forms name="MyCookie" loginUrl="Login.aspx"  timeout="60"

              path="/"   protection="All">

        <credentials>

           <user name="xiaoyang" password="xiaoyang"/>

           <user name="panyan" password="panyan"/>

         </credentials>

      </forms>

 </authentication>

       見上面的  <credentials>節點,就是我們存放的使用者資訊。上面的資訊是以明文(沒有加密)的形式存放。我們也采用加密的方式存放,隻要配置如下:<credentials  passwordFormat="MD5">,配置 passwordFormat的加密方式就行了。那麼使用者在傳輸之前就會被加密。

       還有就是把使用者資訊存儲在資料庫中,我們後面會講述的,也是最常用的方式。

       web.config配置的一些用法

       1.在web.config中添加使用者憑證

       我們之前說過了,ASP.NET的身份驗證中,對于如何存儲使用者憑證提供了很大的靈活性。預設情況下是把憑證存儲在web.config中的。

       我們還是來看看之前配置的一些節點資訊:

 <authentication mode="Forms ">

        <forms name="MyCookie" loginUrl="Login.aspx"  timeout="60"

              path="/"  protection="All">

         <credentials>

           <user name="xiaoyang" password="xiaoyang"/>

           <user name="panyan" password="panyan"/>

         </credentials>

        </forms>

   </authentication>

       在<credentials>中就是我們存儲的使用者的一些資訊。不知道大家是否還記得我們之前已經說過了的Authenticate方法:隻有把使用者資訊存放在了配置檔案中,我們才可以使用這個方法,代碼如下(判斷送出的使用者資訊是否合法):

  bool IsAuthenticate= FormsAuthentication.Authenticate(userName, userPassword);

       2.拒絕匿名使用者通路

       其實這是與使用者授權的問題現關聯的,關于授權問題,我們以後談,這裡隻是簡單的提下,算是預熱吧!

       我們可以拒絕匿名使用者通路我們的網站,隻要配置如下:

  <authorization>  <deny users="?"/>         </authorization>

       談起這個節點,還是有一些話題的,這個我們在專門講述授權的時候具體談。現在我們的重點是驗證!

       Forms驗證一些簡單的使用

       其實對于任何一種驗證來說,無非就是提供輸入使用者資訊的界面,也就是常見的登入頁面。登入頁面可以很簡單:隻要提供輸入使用者名和密碼的輸入框就行了,而登入頁面的功能就是驗證輸入資訊是否正确,如果正确就建立身份驗證的票據并且儲存在cookie中。

 下面就看看一個簡單的頁面以及代碼的實作:

       注:界面很簡單,大家可能會想到ASP.NET現有的Login控件,但是Login是基于MemberShip的。現在談MemberShip還過早,因為我們後面文章專門的講解從Forms驗證到MemberShip的自然過渡,那樣大家就可以很清楚的知道MemberShip到時怎麼回事。

       代碼部分,其實主要是"登入"按鈕背後的代碼:

protected void  btnLogin_Click(object sender, EventArgs e){

if (FormsAuthentication.Authenticate(txtUserName.Text, txtUserPasswork.Text)) {

             FormsAuthentication.RedirectFromLoginPage(txtUserName.Text, false);

        }

     else { throw new Exception("登入失敗!!!");}

}

        代碼的前提是:我們把使用者的資訊存放在了web.config檔案中,因為我們用了Authenticate方法。

       首先代碼就判斷提供的使用者名和密碼是否正确,如果正确,那麼就通過了驗證,那麼我們就調用RedirectFromLoginPage就把使用者定位了他們最初請求的頁面。

       注意:當我們調用RedirectFromLoginPage方法時,RedirectFromLoginPage就建立一個身份驗證的票據,即把使用者的資訊寫入票據中,并且加密,并把票據寫入cookie,然後就把使用者定位了他們最初請求的頁面。我們隻是寫了一行代碼就實作了很多的功能。

      還有一點就是RedirectFromLoginPage方法的第二個參數指出了是否應該建立一個持久性的cookie,即使用者關閉浏覽器後依然保留cookie。我們常常實作"記住我"的功能就是傳入了true.

       當我們登入了之後,要登出也隻要一行代碼:

 protected void btnloginOut_Click(object sender, EventArgs e){

   FormsAuthentication.SignOut();

        }

       Forms驗證中的Cookie問題

       之前我們所見到的示例都是利用非持久性的身份驗證cookie來維持請求之前的身份驗證。這就意味着:如果使用者關閉浏覽器,cookie就期滿失效,下次還需要在此登入。從安全的方面還說,這是個好事。

 身份驗證cookie中儲存的身份驗證票據是ASP.NET應用程式識别使用者的工具。例如,如果一個使用者擁有一個管理者的有效驗證票據,那麼我們的ASP.NET網站就會認為這個使用者就是管理者。

       盡管使用持久化的身份驗證cookie風險很大,但是還是有很多的用處的。例如,如果我們隻是僅僅為了差別不同的使用者,而不是對受限資源的通路進行限制,那麼我們就不要求使用者在每次通路站點時都登入,這樣我們就可以利用持久化的cookie,而且建立持久化的cookie也很簡單,如我們之前用的RedirectFromLoginPage,隻要把方法的第二個參數設定為true就行了。

       除此之外,建立持久化的身份cookie,我們還可以使用SetAuthCookie,并且把第二個參數設定為true。如下:

       FormsAuthentication.SetAuthCookie(txtUserName.Text, true);

       持久化的cookie隻有在調用了FormsAuthentication.SignOut();方法之後才會過期。并且持久化的cookie不會受到web.config中的<forms>節點中設定的逾時的影響。如果我們希望持久化的cookie逾時,我們就要調用FormsAuthentication類的GetAuthCookie方法,設定cookie的期滿日期和時間,并且我們自己手動的把它寫入HTTP響應。

       如下面的代碼,我們建立一個時間為一周的持久化的cookie(代碼加了注釋)

protected void  btnLogin_Click(object sender, EventArgs e){

                //判斷使用者提供的驗證資訊是否正确

    if (FormsAuthentication.Authenticate(txtUserName.Text, txtUserPasswork.Text)){

                        //建立一個持久化的身份驗證cookie

        HttpCookie cookie = FormsAuthentication.GetAuthCookie(txtUserName.Text, true);

        cookie.Expires = DateTime.Now.AddDays(7); //設定cookie的有效時間

        Response.Cookies.Add(cookie); //手動添加到HTTP響應中

                        //跳轉到最初請求的頁面

        Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUserName.Text, true));

                }

                else{

                        throw new Exception("登入失敗!!!");

                }

        }

       其中GetRedirectUrl擷取使用者最初請求的URL

ASP.NET安全問題--Forms驗證(後篇)--實戰篇

       驗證流程講述

       我們首先假設一個場景:使用者現在已經打開了我們的首頁Default.aspx,但是有些資源隻能是登入使用者才可以看到的,那麼如果這個使用者想要檢視這些資源,那麼他就要登入。而且這個使用者已經有了一個帳号。(我們本篇主要的話題是身份驗證,至于建立使用者賬戶是怎麼建立的,我們不關心,方法很多,如直接一個資料庫插入就行了!)

       我們現在就把我們的一些流程說下:

       1.使用者登入,在輸入框中輸入使用者名和密碼資訊

       2.點選登入按鈕後,到資料庫中查詢該使用者是否存在

       3 如果存在,伺服器端代碼就建立一個身份驗證的票據,儲存在cookie中,然後發送到用戶端的浏覽器

       4.使用者已經有了驗證的cookie,那麼就頁面就跳轉到使用者之前請求的頁面

       資料庫準備

       那麼下面我們就開始詳細講述:

       首先,我們我們肯定要先得建立一個資料庫,我們就取名為Login表,建立一個使用者資訊表,我們在在表中建立三個字段UserName,UserPassword,UserRole(大家可以建立更多字段,我這裡隻是示範,大家可以擴充的).  至于表中的資料,大家自己随便插入幾條!

       代碼編寫

       因為我們常常要驗證使用者,是以我們把驗證使用者的代碼寫成一個方法放在App_Code目錄下的Helpers.cs類中

       代碼如下:

public static bool ValidateUser(string username, string password)

{

      然後我們就建立一個登入的頁面Login.aspx,在頁面上面放入兩個TextBox,分别用來供使用者輸入使用者名和密碼。

      放上一個按鈕,用來登入。

      回到Helpers.cs中,我再添加一個方法,來擷取使用者的角色:

public static string  GetRoleForUser(string username ){

   …

    com.CommandText = “Select UseRole m Users Where [email protected];

    com.Parameters.AddWithValue(“@Username”, username);

    …….

    string userRole= (string)com.ExecuteScalar();  

}

      為了啟動Forms驗證,我們還得到web.config檔案中配置,如下:

<authentication mode=”Forms”>

    <forms name=”.mycookie” path=”/” loginUrl=”Login.aspx” protection=”All”

timeout=”40” />

</authentication>

      并且不允許匿名使用者通路我們的網站 :

<authorization>

  <deny users=”?”/>

</authorization>

      然後我們就開始在Login.aspx的登入按鈕下面寫代碼了:

      基本思想如下:

      1.驗證使用者是否存在,

      2.如果存在,同時擷取使用者的角色

      3.建立身份驗證票據和cookie,并且發送到用戶端的浏覽器中

     代碼都加了注釋,通過之前的基礎,相信大家可以對下面的代碼沒有問題。

protected void LoginCallback(object sender, EventArgs e){

    if (Helpers.ValidateUser(UserName.Text, Password.Text)){

        string     rolenames = Helpers.GetRolesForUser(UserName.Text); //擷取使用者的角色

                //建立身份驗證票據

        FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,

                UserName.Text, DateTime.Now, DateTime.Now.AddSeconds(40), false, roles);

        string encryptedTicket = FormsAuthentication.Encrypt(ticket);  //加密票據

                //建立新的cookie

        HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName);

        cookie.Value = encryptedTicket; //把加密後的票據資訊放入cookie

        Response.Cookies.Add(cookie);  //把cookie添加到響應流中

                //把cookie發送到用戶端

        Response.Redirect(FormsAuthentication.GetRedirectUrl(UserName.Text,false),true);

    }

}

      好了,現在如果我們正确的輸入使用者名和密碼,那麼我們的浏覽器中就有了身份驗證的cookie了,現在我們的頁面就要馬上從原來的Login.aspx轉向到Default.aspx頁面了,我們現在把這個轉向的過程在頭腦中把它慢速化,因為我們要分析這個過程。

       在Login.aspx轉向到Default.aspx頁面跳轉的過程中,其實我們在請求Default.aspx頁面,這個我們之前請求的過程沒有任何的差別,也是一樣要經曆ASP.NET的一些生命周期,但是這次我們的浏覽器中已經有了身份驗證的cookie,ASP.NET運作時在處理,在處理Application_AuthenticateRequest事件時就要解析我們的cookie了。其實在之前我們登入之前,在這個事件代碼中也解析了cookie的,隻是那時候沒有找到cookie而以。

       Application_AuthenticateRequest事件的代碼中,其實就是解析cookie,然後把使用者的身份辨別,并且把使用者的身份資訊儲存起來:

void Application_AuthenticateRequest(object sender, EventArgs e){

    HttpApplication app = (HttpApplication)sender;  //擷取身份驗證的cookie

    HttpCookie cookie = Request.Cookies[FormsAuthentication.FormsCookieName];

    if (cookie != null) {

        string encryptedTicket = cookie.Value;//解密cookie中的票據資訊

         FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(encryptedTicket);

        string[] roles = new string[]{ticket.UserData.toString()};//擷取使用者角色資訊

        FormsIdentity identity = new FormsIdentity(ticket); //建立使用者辨別

                //建立使用者的主體資訊

        System.Security.Principal.GenericPrincipal user =

        new System.Security.Principal.GenericPrincipal(identity, roles);

        app.Context.User = user;

    }

}

      我們看到最後一行代碼:app.Context.User = user;,把使用者的身份以及角色資訊儲存在了User屬性中。

      我們就可以在頁面中通過如下方法判斷使用者是否登入了:   

 if (Page.User.Identity.IsAuthenticated)

      用下面的方法判斷使用者是否屬于某個角色: 

if (Page.User.IsInRole("Admin")

      其實這個我們之前講過了的Identity,IPrincipal概念有關,不清楚的可以看看之前的文章!

      代碼到這裡,今天也寫完了,有關身份驗證的問題就要講完了,還差一個問題沒有講述:自定義身份驗證以及開發自定義的HttpModule.

      之後的的文章将講述授權的問題。

轉載于:https://www.cnblogs.com/tangself/archive/2012/04/04/2432336.html