ASP.NET生命周期中的驗證以及身份驗證模塊
前言:最近一直很忙,沒有來得及把之前的文章寫完,已經(jīng)有不少朋友在給我留言催我了,很感謝朋友們的關(guān)注,也跟大家說聲對不起!
本篇主要一下話題:
1.ASP.NET運行的生命周期的驗證
2.身份驗證模塊
3.授權(quán)模塊
1.ASP.NET運行的生命周期的驗證
其實在ASP.NET中每一個請求都進行了驗證和授權(quán)的。進行驗證和授權(quán)的過程實際上是通過觸發(fā)相應(yīng)的事件來完成的。
在講述驗證事件之前,首先清晰一個流程:ASP.NET運行時接到一個請求的處理的流程。
先把流程描述一下,使得大家有個總體把握:一個請求來了,經(jīng)過IIS,通過ISAPI,就到達了ASP.NET的管道中,然后經(jīng)過一些的轉(zhuǎn)化和包裝,然后ASP.NET運行時開始處理這個請求了,然后是進行驗證和授權(quán),然后再進行一系列的處理,最后確定請求是是什么文件,如果是.aspx的,那么然后就開始頁面的生命周期,如下圖。
下面就處理請求時候觸發(fā)的事件順序如下:
BeginRequest: 開發(fā)處理請求,是處理ASP.NET請求時觸發(fā)的第一個事件
AuthenticateRequest:處理身份驗證
...
AuthorizeRequest:處理授權(quán)
...
所以大家可以看出,其實在請求的處理過程中,身份的驗證和授權(quán)發(fā)生的時期是很早的。而且有關(guān)驗證的一些信息,如用戶名和角色在處理完這兩個事件之后就已經(jīng)確定,并且填充。下面我想用個圖來講述:
一般對于請求的驗證和授權(quán),我們是希望也應(yīng)該自己控制這個過程的,所以我們可以在AuthenticateRequest和AuthorizeRequest的事件處理中加入我們自己的代碼。一般在網(wǎng)站中加入 Global.asax文件。
AuthenticateRequest事件:
當一個請求需要進行身份驗證時,HttpApplication對象就會觸發(fā)AuthenticateRequest事件,這也意味著每次對ASP.NET應(yīng)用程序進行頁面請求時都會觸發(fā)這個事件。
在這個事件中實際上是調(diào)用相應(yīng)的身份驗證模塊來處理身份驗證的。例如對于Forms身份驗證模塊而言,就是從加密的cookie中提取用戶信息。
AuthorizeRequest事件:
AuthorizeRequest事件是在AuthenticateRequest事件中通過了身份驗證時候才觸發(fā)的。AuthorizeRequest事件調(diào)用相應(yīng)的授權(quán)模塊來檢查用戶是否被授權(quán)訪問他們請求的資源。因為在AuthenticateRequest事件完成之后就已經(jīng)有了用戶的表示Identity和IPricipal,也就知道了用戶名和角色的信息。
2.身份驗證模塊
身份驗證是利用ASP.NET中的身份驗證模塊來實現(xiàn)的。在ASP.NET中內(nèi)置有四個驗證模塊:
DefaultAuthenticateModule,FormsAuthenticateModule,WindowsAuthenticateModule,PassportAuthenticateModule.他們都實現(xiàn)了IHttpModule接口,當然,如果需要,我們也可以實現(xiàn)自定義的驗證模塊。
從驗證模塊就可以看出我們一般的身份驗證是怎么進行的,決定采用個驗證模塊是由我們決定采用哪種身份驗證決定的,如Forms驗證就是用了FormsAuthenticateModule來處理的。而且還要配置web.config文件
中的<authentication/>元素。
下面我們就先來看看身份驗證模塊的實現(xiàn)(偽碼)
大家可以看到,其實在模塊的Init方法中就訂閱了AuthenticateRequest事件,而我們在Global.asax中寫的代碼就是我們具體處理的代碼:
還有一點要注意的就是:每個模塊都有一個Authenticate事件。
下面就說說常用的兩個個驗證模塊,因為大同小異:
WindowsAuthenticateModule:
WindowsAuthenticateModule是和IIS身份驗證聯(lián)合試用的,當web.config 的中配置如下:
<authentication mode="Windows"/>
此時,這個模塊就激活了,在Global.asax文件中就的Application_Authenticate(object sender,eventArgs e)就是給Windows驗證用的。
這里有一個問題要澄清:如果是我們配置的是Windows身份驗證,我們在Application_Authenticate中就只能寫和Windows身份驗證有關(guān)的代碼,如果是配置的是Forms驗證,我們在Application_Authenticate就只能寫和Forms有關(guān)的代碼,如獲取cookie信息等。也就是說,Application_Authenticate方法是"一法多用"。
接著談 Windows驗證,在上面的處理程序中,我們可以創(chuàng)建自己的用戶信息,如我們創(chuàng)建一個WindowsPrincipal類的實例(實現(xiàn)了IPrincipal接口,包含用戶名和角色的信息),然后它賦值給 HttpContext.User屬性。這正如我們之前說的,驗證事件執(zhí)行完之后,我們就知道了這個請求的發(fā)起者的用戶名和角色信息。
FormsAuthenticateModule:
首先還是要配置:<authentication mode="Forms"/>.
FormsAuthenticateModule可以利用cookie解析保存在cookie中的用戶的信息,并且創(chuàng)建一個GenericPrincipal,把用戶名和角色信息保存在其中,然后賦值給User屬性,以備后用。
3.授權(quán)模塊
在ASP.NET中內(nèi)置的授權(quán)模塊主要有兩個:FileAuthorizationModule和UrlAuthorizationModule。他們也實現(xiàn)了IHttpModule接口。這些模塊可以參照所試用的身份驗證類型來決定到底采用哪個授權(quán)模塊:
如果試用的是Windows身份驗證,那么在授權(quán)檢查的時候就會使用FileAuthorizationModule;
如果在web.config中提供了<authorization/>元素,那么就會采用UrlAuthorizationModule。如下面的:
FileAuthorizationModule:
如果使用 Windows身份驗證,就會采用FileAuthorizationModule模塊。這個模塊可以處理Authorization事件,并且能夠?qū)IS提供的請求的令牌和目標資源執(zhí)行訪問檢查。而且這也用到了系統(tǒng)的ACL(訪問控制列表).
例 如,如果請求的資源是Default.aspx,當前的用戶是xiaoyang,那么FileAuthorizationModule就會執(zhí)行訪問檢查,看看xiaoyang時候具備訪問Default.aspx的讀的權(quán)限,如果在Windows的用戶賬戶中有xiaoyang這個賬戶,并且具有訪問的權(quán)限,那么請求成功,否則,F(xiàn)ileAuthorizationModule就把Reponse.StatusCode設(shè)置為401(未授權(quán)),之后請求就結(jié)束了。
UrlAuthorizationModule:
和上面的處理模塊不一樣,不管使用何種類型的身份驗證,只要配置了web.config中的<authorization/>元素,就要使用UrlAuthorizationModule模塊。這個模塊在處理的時候執(zhí)行如下:
1,把<authorization/>中聲明的用戶名和HttpContext.User.Identity進行比較
2.把<authorization/>聲明的角色信息和HttpContext.User.IsInRole比較
如果比較成功就可以訪問相應(yīng)的授權(quán)的資源,否則把Reponse.StatusCode設(shè)置為401(未授權(quán)),之后請求就結(jié)束了。
今天就到這里,下篇我們詳細談?wù)凢orms驗證和授權(quán)的各種細節(jié)。