十年網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專業(yè)推廣+無(wú)憂售后,網(wǎng)站問(wèn)題一站解決
Asp.net的身份驗(yàn)證有有三種,分別是"Windows | Forms | Passport",其中又以Forms驗(yàn)證用的最多,也最靈活。

創(chuàng)新互聯(lián)總部坐落于成都市區(qū),致力網(wǎng)站建設(shè)服務(wù)有網(wǎng)站設(shè)計(jì)制作、網(wǎng)站建設(shè)、網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃、網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站維護(hù)、公眾號(hào)搭建、小程序制作、軟件開(kāi)發(fā)等為企業(yè)提供一整套的信息化建設(shè)解決方案。創(chuàng)造真正意義上的網(wǎng)站建設(shè),為互聯(lián)網(wǎng)品牌在互動(dòng)行銷(xiāo)領(lǐng)域創(chuàng)造價(jià)值而不懈努力!
Forms 驗(yàn)證方式對(duì)基于用戶的驗(yàn)證授權(quán)提供了很好的支持,可以通過(guò)一個(gè)登錄頁(yè)面驗(yàn)證用戶的身份,將此用戶的身份發(fā)回到客戶端的Cookie,之后此用戶再訪問(wèn)這個(gè) web應(yīng)用就會(huì)連同這個(gè)身份Cookie一起發(fā)送到服務(wù)端。服務(wù)端上的授權(quán)設(shè)置就可以根據(jù)不同目錄對(duì)不同用戶的訪問(wèn)授權(quán)進(jìn)行控制了。
問(wèn)題來(lái)了,在實(shí)際是用中我們往往需要的是基于角色,或者說(shuō)基于用戶組的驗(yàn)證和授權(quán)。對(duì)一個(gè)網(wǎng)站來(lái)說(shuō),一般的驗(yàn)證授權(quán)的模式應(yīng)該是這樣的:根據(jù)實(shí)際需 求把用戶分成不同的身份,就是角色,或者說(shuō)是用戶組,驗(yàn)證過(guò)程不但要驗(yàn)證這個(gè)用戶本身的身份,還要驗(yàn)證它是屬于哪個(gè)角色的。
而訪問(wèn)授權(quán)是根據(jù)角色來(lái)設(shè)置的,某些角色可以訪問(wèn)哪些資源,不可以訪問(wèn)哪些資源等等。要是基于用戶來(lái)授權(quán)訪問(wèn)將會(huì)是個(gè)很不實(shí)際的做法,用戶有很多,還可能隨時(shí)的增減,不可能在配置文 件中隨時(shí)的為不斷增加的新用戶去增加訪問(wèn)授權(quán)的。
下面大概的看一下Forms的過(guò)程。
Forms身份驗(yàn)證基本原理:
一 身份驗(yàn)證
要采用Forms身份驗(yàn)證,先要在應(yīng)用程序根目錄中的Web.config中做相應(yīng)的設(shè)置:
其中
1.
默認(rèn)情況下,name 的值是 .ASPXAUTH。采用此種方式驗(yàn)證用戶后,以此用戶的信息建立一個(gè)FormsAuthenticationTicket類型的身份驗(yàn)證票,再加密序列 化為一個(gè)字符串,最后將這個(gè)字符串寫(xiě)到客戶端的name指定名字的Cookie中.一旦這個(gè)Cookie寫(xiě)到客戶端后,此用戶再次訪問(wèn)這個(gè)web應(yīng)用時(shí)會(huì) 將連同Cookie一起發(fā)送到服務(wù)端,服務(wù)端將會(huì)知道此用戶是已經(jīng)驗(yàn)證過(guò)的.
再看一下身份驗(yàn)證票都包含哪些信息呢,我們看一下FormsAuthenticationTicket類:
CookiePath: 返回發(fā)出 Cookie 的路徑。注意,窗體的路徑設(shè)置為 /。由于窗體區(qū)分大小寫(xiě),這是為了防止站點(diǎn)中的 URL 的大小寫(xiě)不一致而采取的一種保護(hù)措施。這在刷新 Cookie 時(shí)使用
Expiration: 獲取 Cookie 過(guò)期的日期/時(shí)間。
IsPersistent: 如果已發(fā)出持久的 Cookie,則返回 true。否則,身份驗(yàn)證 Cookie 將限制在瀏覽器生命周期范圍內(nèi)。
IssueDate: 獲取最初發(fā)出 Cookie 的日期/時(shí)間。
Name: 獲取與身份驗(yàn)證 Cookie 關(guān)聯(lián)的用戶名。
UserData :獲取存儲(chǔ)在 Cookie 中的應(yīng)用程序定義字符串。
Version: 返回字節(jié)版本號(hào)供將來(lái)使用。
2.
默認(rèn)值為 default.aspx。loginUrl指定的頁(yè)面就是用來(lái)驗(yàn)證用戶身份的,一般此頁(yè)面提供用戶輸入用戶名和密碼,用戶提交后由程序來(lái)根據(jù)自己的需要 來(lái)驗(yàn)證用戶的合法性(大多情況是將用戶輸入信息同數(shù)據(jù)庫(kù)中的用戶表進(jìn)行比較),如果驗(yàn)證用戶有效,則生成同此用戶對(duì)應(yīng)的身份驗(yàn)證票,寫(xiě)到客戶端的 Cookie,最后將瀏覽器重定向到用戶初試請(qǐng)求的頁(yè)面.一般是用FormsAuthentication.RedirectFromLoginPage 方法來(lái)完成生成身份驗(yàn)證票,寫(xiě)回客戶端,瀏覽器重定向等一系列的動(dòng)作.
- public static void RedirectFromLoginPage( string userName, bool createPersistentCookie, string strCookiePath );
其中:
userName: 就是此用戶的標(biāo)示,用來(lái)標(biāo)志此用戶的唯一標(biāo)示,不一定要映射到用戶賬戶名稱.
createPersistentCookie: 標(biāo)示是否發(fā)出持久的 Cookie。
若不是持久Cookie,Cookie的有效期Expiration屬性有當(dāng)前時(shí)間加上web.config中timeout的時(shí)間,每次請(qǐng)求頁(yè)面時(shí),在 驗(yàn)證身份過(guò)程中,會(huì)判斷是否過(guò)了有效期的一半,要是的話更新一次cookie的有效期;若是持久cookie,Expiration屬性無(wú)意義,這時(shí)身份 驗(yàn)證票的有效期有cookie的Expires決定,RedirectFromLoginPage方法給Expires屬性設(shè)定的是50年有效期。
strCookiePath: 標(biāo)示將生成的Cookie的寫(xiě)到客戶端的路徑,身份驗(yàn)證票中保存這個(gè)路徑是在刷新身份驗(yàn)證票Cookie時(shí)使用(這也是生成Cookie的Path),若沒(méi)有strCookiePath 參數(shù),則使用web.config中 path屬性的設(shè)置。
這里可以看到,此方法參數(shù)只有三個(gè),而身份驗(yàn)證票的屬性有七個(gè),不足的四個(gè)參數(shù)是這么來(lái)的:
IssueDate: Cookie發(fā)出時(shí)間由當(dāng)前時(shí)間得出,
Expiration:過(guò)期時(shí)間由當(dāng)前時(shí)間和下面要說(shuō)的
UserData: 這個(gè)屬性可以用應(yīng)用程序?qū)懭胍恍┯脩舳x的數(shù)據(jù),此方法沒(méi)有用到這個(gè)屬性,只是簡(jiǎn)單的將此屬性置為空字符串,請(qǐng)注意此屬性,在后面我們將要使用到這個(gè)屬性。
Version: 版本號(hào)由系統(tǒng)自動(dòng)提供.
RedirectFromLoginPage 方法生成生成身份驗(yàn)證票后,會(huì)調(diào)用FormsAuthentication.Encrypt 方法,將身份驗(yàn)證票加密為字符串,這個(gè)字符串將會(huì)是以.ASPXAUTH為名字的一個(gè)Cookie的值。這個(gè)Cookie的其它屬性的生 成:Domain,Path屬性為確省值,Expires視createPersistentCookie參數(shù)而定,若是持久 cookie,Expires設(shè)為50年以后過(guò)期;若是非持久cookie,Expires屬性不設(shè)置。
生成身份驗(yàn)證Cookie后,將此Cookie加入到Response.Cookies中,等待發(fā)送到客戶端。
最后RedirectFromLoginPage方法調(diào)用FormsAuthentication.GetRedirectUrl 方法獲取到用戶原先請(qǐng)求的頁(yè)面,重定向到這個(gè)頁(yè)面。
3.
以上就是基于Forms身份驗(yàn)證的過(guò)程,它完成了對(duì)用戶身份的確認(rèn)。下面介紹基于Forms身份驗(yàn)證的訪問(wèn)授權(quán)。
二 訪問(wèn)授權(quán)
驗(yàn)證了身份,是要使用這個(gè)身份,根據(jù)不同的身份我們可以進(jìn)行不同的操作,處理,最常見(jiàn)的就是對(duì)不同的身份進(jìn)行不同的授權(quán),F(xiàn)orms驗(yàn)證就提供這樣 的功能。Forms授權(quán)是基于目錄的,可以針對(duì)某個(gè)目錄來(lái)設(shè)置訪問(wèn)權(quán)限,比如,這些用戶可以訪問(wèn)這個(gè)目錄,那些用戶不能訪問(wèn)這個(gè)目錄。
同樣,授權(quán)設(shè)置是在你要控制的那個(gè)目錄下的web.config文件中來(lái)設(shè)置:
- roles="comma-separated list of roles"
- verbs="comma-separated list of verbs" />
- roles="comma-separated list of roles"
- verbs="comma-separated list of verbs" />
1. users:一個(gè)逗號(hào)分隔的用戶名列表,這些用戶名已被授予對(duì)資源的訪問(wèn)權(quán)限。問(wèn)號(hào) (?) 允許匿名用戶;星號(hào) (*) 允許所有用戶。
2. roles:一個(gè)逗號(hào)分隔的角色列表,這些角色已被授予對(duì)資源的訪問(wèn)權(quán)限。
3. verbs:一個(gè)逗號(hào)分隔的 HTTP 傳輸方法列表,這些 HTTP 傳輸方法已被授予對(duì)資源的訪問(wèn)權(quán)限。注冊(cè)到 ASP.NET 的謂詞為 GET、HEAD、POST 和 DEBUG。
在運(yùn)行時(shí),授權(quán)模塊迭代通過(guò)
那么這些user 和roles又是如何得到的呢?下面看一下授權(quán)的詳細(xì)過(guò)程:
1. 一旦一個(gè)用戶訪問(wèn)這個(gè)網(wǎng)站,就行登錄確認(rèn)了身份,身份驗(yàn)證票的cookie也寫(xiě)到了客戶端。之后,這個(gè)用戶再次申請(qǐng)這個(gè)web的頁(yè)面,身份驗(yàn)證票的 cookie就會(huì)發(fā)送到服務(wù)端。在服務(wù)端,asp.net為每一個(gè)http請(qǐng)求都分配一個(gè)HttpApplication對(duì)象來(lái)處理這個(gè)請(qǐng)求,在 HttpApplication.AuthenticateRequest事件后,安全模塊已建立用戶標(biāo)識(shí),就是此用戶的身份在web端已經(jīng)建立起來(lái),這 個(gè)身份完全是由客戶端發(fā)送回來(lái)的身份驗(yàn)證票的cookie建立的。
2. 用戶身份在HttpContext.User 屬性中,在頁(yè)面中可以通過(guò)Page.Context 來(lái)獲取同這個(gè)頁(yè)面相關(guān)的HttpContext對(duì)象。對(duì)于Forms驗(yàn)證,HttpContext.User屬性是一個(gè)GenericPrincipal 類型的對(duì)象,GenericPrincipal只有一個(gè)公開(kāi)的屬性Identity,有個(gè)私有的m_role屬性,是string[]類型,存放此用戶是 屬于哪些role的數(shù)組,還有一個(gè)公開(kāi)的方法IsInRole(string role),來(lái)判斷此用戶是否屬于某個(gè)角色。
由于身份驗(yàn)證票的cookie中根本沒(méi)有提供role這個(gè)屬性,就是說(shuō)Forms身份驗(yàn)證票沒(méi)有提供此用戶的role信息,所以,對(duì)于Forms驗(yàn)證,在服務(wù)端得到的GenericPrincipal 用戶對(duì)象的m_role屬性永遠(yuǎn)是空的。
3. GenericPrincipal. Identity 屬性是一個(gè)FormsIdentity類型的對(duì)象,這個(gè)對(duì)象有個(gè)Name屬性,就是此用戶的標(biāo)示,訪問(wèn)授權(quán)就是將此屬性做為user來(lái)進(jìn)行授權(quán)驗(yàn)證的。 FormsIdentity還有一個(gè)屬性,就是Ticket屬性,此屬性是身份驗(yàn)證票FormsAuthenticationTicket類型,就是之前 服務(wù)器寫(xiě)到客戶端的身份驗(yàn)證票。
服務(wù)器在獲取到身份驗(yàn)證票FormsAuthenticationTicket對(duì)象后,查看這個(gè)身份驗(yàn)證票是不是非持久的身份驗(yàn)證,是的話要根據(jù) web.config中timeout屬性設(shè)置的有效期來(lái)更新這個(gè)身份驗(yàn)證票的cookie。