ASP.NET使用HTTP管道模型來處理HTTP請求,當一個HTTP請求到達Web服務器時,這個請求按「HttpModule >>Page/HttpHandle >>HttpModule」這樣的順序前後經過各個HttpModule和Page/HttpHandle對象,在這些對象中將觸發應用程序事件。事件的觸發順序以下圖所示。web
從上圖能夠看到,在觸發頁面事件(即正式對頁面進行處理)以前,將先觸發Application_AuthenticateRequest、Application_PostAuthenticateRequest、Application_AuthorizeRequest、Application_PostAuthorizeRequest這四個事件,經過這四個事件,咱們能夠自定義用戶身份驗證,再進行正式的頁面處理。數組
1. AuthenticateRequest事件瀏覽器
當安全模塊已創建用戶標識時發生。AuthenticateRequest事件發出信號表示配置的身份驗證機制已對當前請求進行了身份認證,預訂AuthenticateRequest事件可確保在處理附加的模塊或事件處理程序以前對請求進行身份認證。安全
2. PostAuthenticateRequest事件服務器
當安全模塊已創建用戶標識時發生。有時咱們使用成員組Context.User及Forms驗證來實現用戶的登陸,可是成員組所提供的功能有限,當須要能訪問到本身定義的我的信息時,這時咱們就能利用此事件來處理。cookie
3. AuthorizeRequest事件架構
當安全模塊已驗證用戶受權時發生。AuthorizeRequest事件發出信號表示ASP.NET已對當前請求進行了受權。預訂AuthorizeRequest事件可確保在處理附加的模塊或事件處理程序以前對請求進行身份驗證和受權。 ide
4.PostAuthorizeRequest事件函數
在當前請求的用戶已獲受權時發生。PostAuthorizeRequest事件發出信號表示ASP.NET已對當前請求進行了受權。預訂PostAuthorizeRequest事件可確保在處理附加的模塊或處理程序以前對請求進行身份驗證和受權。加密
1、Form登陸
ASP.NET Forms身份驗證方式一般使用Cookie來存儲用戶的身份驗證票。用戶經過身份認證後,能夠將用戶身份信息保存到客戶端Cookie,當用戶再次訪問其餘頁面時,先將Cookie發送到服務器端,服務器端負責讀取該Cookie中存放的用戶信息。
2、Forms身份驗證的工做原理
當向拒絕匿名用戶訪問的資源發出請求,而且當Forms身份驗證處於激活狀態時,URL受權模塊就會把用戶重定向到登陸頁面。原始請求的URL被保存爲URL參數,方便之後使用。
登陸頁面是一個供用戶輸入憑證(一般指用戶名和密碼)的頁面。若是用戶輸入的是正確的資料,就會建立一個「身份驗證票證」。身份驗證票證中含有通過加密的用戶資料,這個票證將被寫入Cookie並被髮送到客戶端,存放在用戶的硬盤上,而後用戶會被重定向到他們最初請求的URL。
用戶再次請求原始URL時(由於被重定向回URL),身份驗證票證Cookie會被瀏覽器添加到請求中,並被Forms身份驗證模塊獲取。它利用Cookie中的資料填充Context.User屬性(該屬性將在下文詳細介紹)。而URL受權模塊則會利用這個用戶信息來驗證用戶是否已被批准訪問所請求的資源。
固然,咱們還能夠不使用拒絕訪問——登陸頁面——接受訪問這一過程來對用戶進行身份驗證。一般狀況下,用戶能夠利用連接進入登陸頁面而不是被自動重定向到那個頁面。這些狀況下,身份驗證票證被建立,並像對待強行進行的身份驗證那樣,把它保存爲一個Cookie。
3、Forms身份驗證的對象模型
ASP.NET安全架構爲實現Web應用程序的完善的安全模式提供了一個對象模型。登陸到應用程序的用戶根據他們提供的憑證被授予了Principal和Identity。Principal對象表示的是用戶的當前安全上下文,包括用戶的標識和他們所屬的角色。Identity對象表示的是當前用戶。Principal對象是利用Identity對象(表示用戶的標識)建立的,它添加了一些額外信息,好比角色或自定義應用程序數據。
4、Principal對象
Principal對象表示的是經過身份驗證的用戶的組或角色成員,也就是當前用戶的安全上下文。Principal對象在當前HttpContext中能夠被理解爲User屬性。HttpContext.Current.User屬性返回的是一個IPrincipal實例,能夠實現IPrincipal接口的對象。
(1) IPrincipal接口
不一樣的身份驗證模式對安全上下文有不一樣的要求。咱們能夠利用Principal對象協調地表示當前的Principal(安全上下文)。IPrincipal接口能夠定義Principal對象的基本功能。全部Principal對象都必需實現IPrincipal——System.Security.Principal命名空間的一部分。IPrincipal接口的成員以下所示:
名稱 |
類型 |
描述 |
Identity |
屬性 |
獲取當前Principal對象的Identity對象 |
IsInRole(string roleName) |
方法 |
能夠判斷當前Principal對象是否屬於指定的角色。 |
(2)GenericPrincipal類
GenericPrincipal類定義了IPrincipal接口的大部分基本實現,命名空間爲System. Security.Principal。咱們能夠建立一個在當前請求的整個生命週期中都要使用的GenericPrincipal類實例,並把它賦值給HttpContext.Current.User屬性。GenericPrincipal的構造函數以下所述:
//identity:實現了IIdentity接口的對象;roles:表示角色的字符串數組
public GenericPrincipal ( IIdentity identity, string[] roles)
GenericPrincipal類中的IslnRole方法經過把角色值和在字符串數組中定義的角色進行比較來判斷當前用戶的角色是否合法。
2. Identity對象
Identity對象用於表示當前用戶的標識,即表示一個用戶是否經過身份驗證。在當前上下文環境中,能夠經過HttpContext.Current.User.Identity.Name屬性獲取Identity對象。
(1) IIdentity接口
全部的Identity對象都必須實現IIdentity接口。與IPrincipal接口同樣,IIdentity接口也定義在System.Security.Principal命名空間下面,它的成員以下所示:
名稱 |
類型 |
描述 |
AuthenticationType |
屬性 |
獲取所使用身份驗證的類型,即Forms身份驗證、Windows身份驗證、PassPort身份驗證。 |
IsAuthenticated |
屬性 |
獲取一個值,該值指示是否驗證了用戶。 |
Name |
屬性 |
獲取當前用戶的名稱。 |
(2) FormsIdentity 類
FormsIdentity類表示一個使用Forms身份驗證進行了身份驗證的用戶標識,命名空間爲System.Web.Security。FormsIdentity類由FormsAuthenticationModule(ASP.NET內置的身份驗證模塊)在通過Forms身份驗證對用戶進行身份驗證時使用。使用從Forms身份驗證Cookie或URL解密的 FormsAuthenticationTicket(身份驗證票據)建立一個FormsIdentity的實例。而後,使用此FormsIdentity類的新實例構造一個新的GenericPrincipal對象,該對象將設置爲當前HttpContext的User屬性的值。 FormsIdentity的構造函數:
//ticket:此標識所基於的身份驗證票。 //類型:System.Web.Security.FormsAuthenticationTicket public FormsIdentity( FormsAuthenticationTicket ticket )
下表列出了FormsIdentity類中幾個經常使用的屬性。
名稱 |
描述 |
AuthenticationType |
獲取通過身份驗證的標識的類型。 |
IsAuthenticated |
獲取一個指示是否發生了身份驗證的值。 |
Name |
獲取Forms標識的用戶名。 |
Ticket |
獲取Forms身份驗證用戶標識的FormsAuthenticationTicket。 |
咱們能夠看到,FormsIdentity在IIdentity接口的基礎上又增長了Ticket屬性,這個屬性提供了Forms身份驗證票證,這樣咱們就能夠在自定義的Forms身份驗證中獲取這個票證。
5、 Forms身份驗證的API
1. FormsAuthentication類
FormsAuthentication類用於輔助咱們完成窗體驗證,並進一步完成用戶登陸等功能。該類位於System.Web.dll程序集的System.Web.Security命名空間中。一般在Web站點項目中能夠直接使用這個類,若是是在類庫項目中使用這個類,請確保引用了System.Web.dll。下表列出了FormsAuthentication類的經常使用屬性。
屬性 |
描述 |
DefaultUrl |
獲取在沒有指定重定向URL時FormsAuthentication類將重定向到的URL。 |
獲取用於存儲Forms身份驗證票證的Cookie 名稱。 |
|
獲取 Forms 身份驗證 Cookie 的路徑。 |
|
獲取 FormsAuthentication 類將重定向到的登陸頁的 URL。 |
FormsAuthentication還提供了兩個重要的方法,分別是Encrypt和Decrypt,顧名思義,這兩個方法分別提供了對身份驗證票據的加密和解密的功能。
Encrypt方法建立一個字符串,其中包含適用於HTTP Cookie的加密的Forms身份驗證票證。該方法是靜態方法,能夠經過如下方式調用。
//參數newAuthTicket:用於建立加密的 Forms 身份驗證票證的 FormsAuthenticationTicket 對象。 //返回值:一個字符串,其中包含加密的 Forms 身份驗證票證。 string cookieValue = FormsAuthentication.Encrypt(newAuthTicket); Decrypt方法建立一個FormsAuthenticationTicket對象,此對象將根據傳遞給該方法的加密的Forms身份驗證票證而定。與Encrypt同樣,該方法也定義爲靜態方法,調用方式以下所示。 //參數authCookie.Value:一個HttpCookie,表示加密的身份驗證票 //返回值:解密後的身份驗證票 FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
2. FormsAuthenticationTicket類
前面咱們已經講過,身份驗證票證是通過加密並做爲HTTP Cookie保存在各個請求之間的信息。票證主要用於支持Forms身份驗證模塊檢驗用戶是否已經經過驗證。
FormsAuthenticationTicket實例中含有咱們但願維持的未加密格式的用戶信息,咱們能夠經過一組屬性訪問該信息。能夠經過三個重載的構造函數來實例化FormsAuthenticationTicket類,具體使用哪一個構造函數須要根據實際需求而定,構造函數的定義以下表所示。
名稱 |
描述 |
public FormsAuthenticationTicket ( string name, bool isPersistent, int timeout) |
使用cookie名和過時信息初始化 FormsAuthenticationTicket 類的新實例。 |
public FormsAuthenticationTicket ( int version,string name,DateTime issueDate, DateTime expiration, bool isPersistent, tring userData) |
使用Cookie名、版本、過時日期、發佈日期、持久性以及用戶特定的數據初始化FormsAuthenticationTicket類的新實例。Cookie路徑設置爲在應用程序的配置文件中創建的默認值。 |
public FormsAuthenticationTicket ( int version, string name, DateTime issueDate, DateTime expiration, bool isPersistent,string userData,string cookiePath) |
使用cookie名、版本、目錄路徑、發佈日期、過時日期、持久性以及用戶定義的數據初始化 FormsAuthenticationTicket類的新實例。 |
參數說明:
version: 票證的版本號。
name:與身份驗證票關聯的用戶名。
issueDate:票證發出時的本地日期和時間。
expiration:票證過時時的本地日期和時間。
isPersistent:若是票證將存儲在持久性Cookie(跨瀏覽器會話保存),則爲true;不然爲false。若是該票證存儲在URL中,將忽略此值。
userData:存儲在票證中的用戶特定的數據。
cookiePath:票證存儲在Cookie中時的路徑。
FormsAuthenticationTicket類還提供了一套完整的與上面的參數對應的屬性,以下表所示。
名稱 |
描述 |
CookiePath |
獲取Forms身份驗證票證的Cookie 路徑。 |
Expiration |
獲取Forms身份驗證票證過時時的本地日期和時間。 |
Expired |
獲取一個值,它指示Forms身份驗證票證是否已過時。 |
IsPersistent |
獲取一個值,該值指示包含Forms身份驗證票證信息的Cookie是否爲持久性的。 |
IssueDate |
獲取最初發出Forms身份驗證票證時的本地日期和時間。 |
Name |
獲取與Forms身份驗證票相關聯的用戶名。 |
UserData |
獲取一個存儲在票證中的用戶特定的字符串。 |
Version |
獲取票證的版本號。 |
6、配置Forms身份驗證
使用Forms身份驗證以前,須要正確地配置web.config,包括兩個元素:<authentication/>和<authorization/>。
1. <authentication/>元素
<authentication/>元素只能在應用程序根文件夾中的web.config中使用。試圖在子文件夾中使用這個元素只會引起錯誤。這就代表,每一個應用程序只能定義一個身份驗證類型,若是咱們但願在子文件夾中使用一個不一樣的身份驗證類型,就必須把它定義爲一個獨立的應用程序。在Forms身份驗證中,<authentication/>的配置一般會像這樣:
<system.web> <authentication mode="Forms"> <forms loginUrl="~/User/Login.aspx" name=".ASPXAUTH" defaultUrl="User/Default.aspx" timeout="30" path="/" /> </authentication> </system.web>
下表說明了各個屬性的做用。
名稱 |
說明 |
mode |
必選的屬性。 指定應用程序的默認身份驗證模式。 有四個可選值,分別是Forms、Windows、Passport、None |
loginUrl |
可選的屬性。 指定若是找不到任何有效的身份驗證Cookie,將請求重定向到的用於登陸的URL。 |
name |
可選的屬性。 指定要用於身份驗證的HTTP Cookie。若是正在一臺服務器上運行多個應用程序而且每一個應用程序都須要惟一的Cookie,則必須在每一個應用程序的web.config文件中配置Cookie名稱。 默認值爲 ".ASPXAUTH"。 |
defaultUrl |
可選的屬性。 定義在身份驗證以後用於重定向的默認URL。 |
timeout |
可選的屬性。 指定Cookie過時前逝去的時間(以整數分鐘爲單位)。 |
path |
可選的屬性。 爲應用程序發出的Cookie指定路徑。 默認值是斜槓 (/),這是由於大多數瀏覽器是區分大小寫,若是路徑大小寫不匹配,瀏覽器不會送回Cookie。 |
2. <authorization/>元素
<authorization/>元素針對受權進行配置,能夠經過該元素指定應用程序某個目錄的訪問權限。該元素的格式通常以下面所示: <system.web> <authorization> <allow users="*" /> <deny users="?" /> </authorization> </system.web>
allow: 向受權規則映射添加一條容許對資源的訪問的受權規則。
deny:向受權規則映射添加一條拒絕對資源的訪問的受權規則。
users:必選的String屬性。一個逗號分隔的用戶名列表,這些用戶名被拒絕對資源進行訪問。問號(?)表示拒絕匿名用戶,星號(*)表示拒絕全部用戶賬戶訪問。
7、 實現Forms身份驗證的基本流程
總的來講,Forms身份驗證可分爲兩大塊:認證與受權。具體步驟以下所示。
1. 認證
2. 受權
8、移除沒必要要的身份驗證模塊
ASP.NET默認集成了提供Windows身份驗證、Passport身份驗證等功能的HttpModule,若是咱們使用了Forms身份驗證方式,則須要移除這些沒必要要的模塊。具體以下所示。
<httpModules> <remove name="WindowsAuthentication" /> <remove name="PassportAuthentication" /> <remove name="FileAuthorization" /> <remove name="AnonymousIdentification" /> </httpModules>
9、簡單案例
有空再完善!是在登陸的時候返回驗證票,請求的時候在AuthenticateRequest 事件中獲取驗證票解密就能夠了!