ASP.net Forms驗證Demo第2/3頁
更新時間:2009年01月03日 00:47:41 作者:
Asp.net中基于Forms驗證的角色驗證授權(quán)
Asp.net的身份驗證有有三種,分別是"Windows | Forms | Passport",其中又以Forms驗證用的最多,也最靈活。
Forms 驗證方式對基于用戶的驗證授權(quán)提供了很好的支持,可以通過一個登錄頁面驗證用戶的身份,將此用戶的身份發(fā)回到客戶端的Cookie,之后此用戶再訪問這個web應(yīng)用就會連同這個身份Cookie一起發(fā)送到服務(wù)端。服務(wù)端上的授權(quán)設(shè)置就可以根據(jù)不同目錄對不同用戶的訪問授權(quán)進(jìn)行控制了。
問題來了,在實際是用中我們往往需要的是基于角色,或者說基于用戶組的驗證和授權(quán)。對一個網(wǎng)站來說,一般的驗證授權(quán)的模式應(yīng)該是這樣的:根據(jù)實際需求把用戶分成不同的身份,就是角色,或者說是用戶組,驗證過程不但要驗證這個用戶本身的身份,還要驗證它是屬于哪個角色的。而訪問授權(quán)是根據(jù)角色來設(shè)置的,某些角色可以訪問哪些資源,不可以訪問哪些資源等等。要是基于用戶來授權(quán)訪問將會是個很不實際的做法,用戶有很多,還可能隨時的增減,不可能在配置文件中隨時的為不斷增加的新用戶去增加訪問授權(quán)的。
下面大概的看一下Forms的過程。
Forms身份驗證基本原理:
一 身份驗證
要采用Forms身份驗證,先要在應(yīng)用程序根目錄中的Web.config中做相應(yīng)的設(shè)置:
<authentication mode="forms">
<forms name=".ASPXAUTH" loginUrl="/login.aspx" timeout="30" path= "/">
</forms>
</authentication>
其中<authentication mode= "forms"> 表示本應(yīng)用程序采用Forms驗證方式。
1. <forms>標(biāo)簽中的name表示指定要用于身份驗證的 HTTP Cookie。默認(rèn)情況下,name 的值是 .ASPXAUTH。采用此種方式驗證用戶后,以此用戶的信息建立一個FormsAuthenticationTicket類型的身份驗證票,再加密序列化為一個字符串,最后將這個字符串寫到客戶端的name指定名字的Cookie中.一旦這個Cookie寫到客戶端后,此用戶再次訪問這個web應(yīng)用時會將連同Cookie一起發(fā)送到服務(wù)端,服務(wù)端將會知道此用戶是已經(jīng)驗證過的.
再看一下身份驗證票都包含哪些信息呢,我們看一下FormsAuthenticationTicket類:
CookiePath: 返回發(fā)出 Cookie 的路徑。注意,窗體的路徑設(shè)置為 /。由于窗體區(qū)分大小寫,這是為了防止站點中的 URL 的大小寫不一致而采取的一種保護(hù)措施。這在刷新 Cookie 時使用
Expiration: 獲取 Cookie 過期的日期/時間。
IsPersistent: 如果已發(fā)出持久的 Cookie,則返回 true。否則,身份驗證 Cookie 將限制在瀏覽器生命周期范圍內(nèi)。
IssueDate: 獲取最初發(fā)出 Cookie 的日期/時間。
Name: 獲取與身份驗證 Cookie 關(guān)聯(lián)的用戶名。
UserData :獲取存儲在 Cookie 中的應(yīng)用程序定義字符串。
Version: 返回字節(jié)版本號供將來使用。
2. <forms>標(biāo)簽中的loginUrl指定如果沒有找到任何有效的身份驗證 Cookie,為登錄將請求重定向到的 URL。默認(rèn)值為 default.aspx。loginUrl指定的頁面就是用來驗證用戶身份的,一般此頁面提供用戶輸入用戶名和密碼,用戶提交后由程序來根據(jù)自己的需要來驗證用戶的合法性(大多情況是將用戶輸入信息同數(shù)據(jù)庫中的用戶表進(jìn)行比較),如果驗證用戶有效,則生成同此用戶對應(yīng)的身份驗證票,寫到客戶端的Cookie,最后將瀏覽器重定向到用戶初試請求的頁面.一般是用FormsAuthentication.RedirectFromLoginPage 方法來完成生成身份驗證票,寫回客戶端,瀏覽器重定向等一系列的動作.
public static void RedirectFromLoginPage( string userName, bool createPersistentCookie, string strCookiePath );
其中:
userName: 就是此用戶的標(biāo)示,用來標(biāo)志此用戶的唯一標(biāo)示,不一定要映射到用戶賬戶名稱.
createPersistentCookie: 標(biāo)示是否發(fā)出持久的 Cookie。
若不是持久Cookie,Cookie的有效期Expiration屬性有當(dāng)前時間加上web.config中timeout的時間,每次請求頁面時,在驗證身份過程中,會判斷是否過了有效期的一半,要是的話更新一次cookie的有效期;若是持久cookie,Expiration屬性無意義,這時身份驗證票的有效期有cookie的Expires決定,RedirectFromLoginPage方法給Expires屬性設(shè)定的是50年有效期。
strCookiePath: 標(biāo)示將生成的Cookie的寫到客戶端的路徑,身份驗證票中保存這個路徑是在刷新身份驗證票Cookie時使用(這也是生成Cookie的Path),若沒有strCookiePath 參數(shù),則使用web.config中 path屬性的設(shè)置。
這里可以看到,此方法參數(shù)只有三個,而身份驗證票的屬性有七個,不足的四個參數(shù)是這么來的:
IssueDate: Cookie發(fā)出時間由當(dāng)前時間得出,
Expiration:過期時間由當(dāng)前時間和下面要說的<forms>標(biāo)簽中timeout參數(shù)算出。此參數(shù)對非持久性cookie有意義。
UserData: 這個屬性可以用應(yīng)用程序?qū)懭胍恍┯脩舳x的數(shù)據(jù),此方法沒有用到這個屬性,只是簡單的將此屬性置為空字符串,請注意此屬性,在后面我們將要使用到這個屬性。
Version: 版本號由系統(tǒng)自動提供.
RedirectFromLoginPage方法生成生成身份驗證票后,會調(diào)用FormsAuthentication.Encrypt 方法,將身份驗證票加密為字符串,這個字符串將會是以.ASPXAUTH為名字的一個Cookie的值。這個Cookie的其它屬性的生成:Domain,Path屬性為確省值,Expires視createPersistentCookie參數(shù)而定,若是持久cookie,Expires設(shè)為50年以后過期;若是非持久cookie,Expires屬性不設(shè)置。
生成身份驗證Cookie后,將此Cookie加入到Response.Cookies中,等待發(fā)送到客戶端。
最后RedirectFromLoginPage方法調(diào)用FormsAuthentication.GetRedirectUrl 方法獲取到用戶原先請求的頁面,重定向到這個頁面。
3. <forms>標(biāo)簽中的timeout和path,是提供了身份驗證票寫入到Cookie過期時間和默認(rèn)路徑。
以上就是基于Forms身份驗證的過程,它完成了對用戶身份的確認(rèn)。下面介紹基于Forms身份驗證的訪問授權(quán)。
二 訪問授權(quán)
驗證了身份,是要使用這個身份,根據(jù)不同的身份我們可以進(jìn)行不同的操作,處理,最常見的就是對不同的身份進(jìn)行不同的授權(quán),F(xiàn)orms驗證就提供這樣的功能。Forms授權(quán)是基于目錄的,可以針對某個目錄來設(shè)置訪問權(quán)限,比如,這些用戶可以訪問這個目錄,那些用戶不能訪問這個目錄。
同樣,授權(quán)設(shè)置是在你要控制的那個目錄下的web.config文件中來設(shè)置:
<authorization>
<allow users="comma-separated list of users"
roles="comma-separated list of roles"
verbs="comma-separated list of verbs" />
<deny users="comma-separated list of users"
roles="comma-separated list of roles"
verbs="comma-separated list of verbs" />
</authorization>
<allow>標(biāo)簽表示允許訪問,其中的屬性
1. users:一個逗號分隔的用戶名列表,這些用戶名已被授予對資源的訪問權(quán)限。問號 (?) 允許匿名用戶;星號 (*) 允許所有用戶。
2. roles:一個逗號分隔的角色列表,這些角色已被授予對資源的訪問權(quán)限。
3. verbs:一個逗號分隔的 HTTP 傳輸方法列表,這些 HTTP 傳輸方法已被授予對資源的訪問權(quán)限。注冊到 ASP.NET 的謂詞為 GET、HEAD、POST 和 DEBUG。
<deny>標(biāo)簽表示不允許訪問。其中的屬性同上面的。
在運行時,授權(quán)模塊迭代通過 <allow> 和 <deny> 標(biāo)記,直到它找到適合特定用戶的第一個訪問規(guī)則。然后,它根據(jù)找到的第一項訪問規(guī)則是 <allow> 還是 <deny> 規(guī)則來允許或拒絕對 URL 資源的訪問。Machine.config 文件中的默認(rèn)身份驗證規(guī)則是 <allow users="*"/>,因此除非另行配置,否則在默認(rèn)情況下會允許訪問。
那么這些user 和roles又是如何得到的呢?下面看一下授權(quán)的詳細(xì)過程:
1. 一旦一個用戶訪問這個網(wǎng)站,就行登錄確認(rèn)了身份,身份驗證票的cookie也寫到了客戶端。之后,這個用戶再次申請這個web的頁面,身份驗證票的cookie就會發(fā)送到服務(wù)端。在服務(wù)端,asp.net為每一個http請求都分配一個HttpApplication對象來處理這個請求,在HttpApplication.AuthenticateRequest事件后,安全模塊已建立用戶標(biāo)識,就是此用戶的身份在web端已經(jīng)建立起來,這個身份完全是由客戶端發(fā)送回來的身份驗證票的cookie建立的。
2. 用戶身份在HttpContext.User 屬性中,在頁面中可以通過Page.Context 來獲取同這個頁面相關(guān)的HttpContext對象。對于Forms驗證,HttpContext.User屬性是一個GenericPrincipal類型的對象,GenericPrincipal只有一個公開的屬性Identity,有個私有的m_role屬性,是string[]類型,存放此用戶是屬于哪些role的數(shù)組,還有一個公開的方法IsInRole(string role),來判斷此用戶是否屬于某個角色。
由于身份驗證票的cookie中根本沒有提供role這個屬性,就是說Forms身份驗證票沒有提供此用戶的role信息,所以,對于Forms驗證,在服務(wù)端得到的GenericPrincipal 用戶對象的m_role屬性永遠(yuǎn)是空的。
3. GenericPrincipal. Identity 屬性是一個FormsIdentity類型的對象,這個對象有個Name屬性,就是此用戶的標(biāo)示,訪問授權(quán)就是將此屬性做為user來進(jìn)行授權(quán)驗證的。FormsIdentity還有一個屬性,就是Ticket屬性,此屬性是身份驗證票FormsAuthenticationTicket類型,就是之前服務(wù)器寫到客戶端的身份驗證票。
服務(wù)器在獲取到身份驗證票FormsAuthenticationTicket對象后,查看這個身份驗證票是不是非持久的身份驗證,是的話要根據(jù)web.config中timeout屬性設(shè)置的有效期來更新這個身份驗證票的cookie(為避免危及性能,在經(jīng)過了超過一半的指定時間后更新該 Cookie。這可能導(dǎo)致精確性上的損失。持久性 Cookie 不超時。)
4. 在HttpApplication.ResolveRequestCache事件之前,asp.net開始取得用戶請求的頁面,建立HttpHandler控制點。這就意味著,在HttpApplication.ResolveRequestCache事件要對用戶訪問權(quán)限就行驗證,看此用戶或角色是否有權(quán)限訪問這個頁面,之后在這個請求的生命周期內(nèi)再改變此用戶的身份或角色就沒有意義了。
以上是Forms驗證的全過程,可以看出,這個Forms驗證是基于用戶的,沒有為角色的驗證提供直接支持。身份驗證票FormsAuthenticationTicket 中的Name屬性是用戶標(biāo)示,其實還有一個屬性UserData,這個屬性可以由應(yīng)用程序來寫入自定義的一些數(shù)據(jù),我們可以利用這個字段來存放role的信息,從而達(dá)到基于角色驗證的目的。
您可能感興趣的文章:
- 淺談asp.net Forms身份驗證詳解
- 詳解ASP.NET MVC Form表單驗證
- 關(guān)于C#.net winform程序驗證moss的集成身份認(rèn)證實例
- Asp.Net二級域名共享Forms身份驗證、下載站/圖片站的授權(quán)訪問控制
- ASP.NET Internet安全Forms身份驗證方法
- asp.net forms身份驗證,避免重復(fù)造輪子
- asp.net 基于forms驗證的目錄角色權(quán)限的實現(xiàn)
- asp.net Forms身份驗證和基于角色的權(quán)限訪問
- asp.net 特定目錄form驗證
- .net MVC使用IPrincipal進(jìn)行Form登錄即權(quán)限驗證(3)
相關(guān)文章
Community Server專題二:體系結(jié)構(gòu)
Community Server專題二:體系結(jié)構(gòu)...2007-03-03asp.net+jquery Gridview的多行拖放, 以及跨控件拖放
學(xué)習(xí)JQuery時,發(fā)現(xiàn)JQuery只能做單行拖放, 于是花時間做了一個多行拖放的例子, 以備以后使用。2009-11-11WPF實現(xiàn)ScrollViewer滾動到指定控件處
這篇文章主要為大家詳細(xì)介紹了WPF實現(xiàn)ScrollViewer滾動到指定控件處,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06使用Aspose.Cells實現(xiàn)導(dǎo)入導(dǎo)出
這篇文章主要為大家詳細(xì)介紹了如何使用Aspose.Cells實現(xiàn)導(dǎo)入導(dǎo)出,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-12-12silverlight2.0Beta版TextBox輸入中文解決方法
silverlight Beta 2.0 中TetBox輸入漢字,除MS自己的輸入法,其它所有輸入法都會出現(xiàn)輸入的東西會在TextBox中重復(fù)一次的現(xiàn)像,google ,Baidu了一下,大家說好像是silverlight自己的一個BUG,可能會在Repleass的時候修改。2008-10-10asp.net基于HashTable實現(xiàn)購物車的方法
這篇文章主要介紹了asp.net基于HashTable實現(xiàn)購物車的方法,涉及asp.net中HashTable結(jié)合session實現(xiàn)購物車功能的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-12-12ASP.NET 使用application與session對象寫的簡單聊天室程序
寫了快一年的asp.net,application對象還真沒怎么用過??戳丝磿鶕?jù)這兩個對象的特性寫了一個簡單的聊天室程序。真的是非常的簡陋2014-07-07.net decimal保留指定的小數(shù)位數(shù)(不四舍五入)
大家都知道decimal保留指定位數(shù)小數(shù)的時候,.NET自帶的方法都是四舍五入的。那么如何讓decimal保留指定位數(shù)小數(shù)的時候不四舍五入呢,下面通過這篇文中的示例代碼來一起看看吧。2016-12-12