基于窗體的驗(yàn)證是最為普遍的一種驗(yàn)證,使用這種驗(yàn)證方式可以很方便靈活地應(yīng)用到應(yīng)用程序中。窗體驗(yàn)證方式對(duì)基于用戶的驗(yàn)證授權(quán)提供了很好的支持,可以通過一個(gè)登錄頁面驗(yàn)證用戶的身份,將此用戶的身份發(fā)回到客戶端的Cookie,之后此用戶再訪問這個(gè)web應(yīng)用就會(huì)連同這個(gè)身份Cookie一起發(fā)送到服務(wù)端。服務(wù)端上的授權(quán)設(shè)置就可以根據(jù)不同目錄對(duì)不同用戶的訪問授權(quán)進(jìn)行控制了。
要采用窗體驗(yàn)證,先要在應(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驗(yàn)證方式。
(1)<Forms>標(biāo)簽中的name表示指定要用于身份驗(yàn)證的 HTTP Cookie。默認(rèn)情況下,name 的值是 .ASPXAUTH。采用此種方式驗(yàn)證用戶后,以此用戶的信息建立一個(gè)FormsAuthenticationTicket類型的身份驗(yàn)證票,再加密序列化為一個(gè)字符串,最后將這個(gè)字符串寫到客戶端的name指定名字的Cookie中。一旦這個(gè)Cookie寫到客戶端后,此用戶再次訪問這個(gè)web應(yīng)用時(shí)會(huì)將連同Cookie一起發(fā)送到服務(wù)端,服務(wù)端將會(huì)知道此用戶是已經(jīng)驗(yàn)證過的。
再看一下身份驗(yàn)證票都包含哪些信息呢,我們看一下FormsAuthenticationTicket類:
CookiePath: 返回發(fā)出 Cookie 的路徑。注意,窗體的路徑設(shè)置為 /。由于窗體區(qū)分大小寫,這是為了防止站點(diǎn)中的 URL 的大小寫不一致而采取的一種保護(hù)措施。這在刷新 Cookie 時(shí)使用。
Expiration: 獲取 Cookie 過期的日期/時(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)供將來使用。
(2) <Forms>標(biāo)簽中的loginUrl指定如果沒有找到任何有效的身份驗(yàn)證Cookie,為登錄將請(qǐng)求重定向到的 URL。默認(rèn)值為 Login.aspx。loginUrl指定的頁面就是用來驗(yàn)證用戶身份的,一般此頁面提供用戶輸入用戶名和密碼,用戶提交后由程序來根據(jù)自己的需要來驗(yàn)證用戶的合法性(大多情況是將用戶輸入信息同數(shù)據(jù)庫中的用戶表進(jìn)行比較),如果驗(yàn)證用戶有效,則生成同此用戶對(duì)應(yīng)的身份驗(yàn)證票,寫到客戶端的Cookie,最后將瀏覽器重定向到用戶初試請(qǐng)求的頁面,一般是用FormsAuthentication.RedirectFromLoginPage 方法來完成生成身份驗(yàn)證票,寫回客戶端,瀏覽器重定向等一系列的動(dòng)作。RedirectFromLoginPage 方法含有3個(gè)參數(shù),函數(shù)定義如下:
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)前時(shí)間加上web.config中timeout的時(shí)間,每次請(qǐng)求頁面時(shí),在驗(yàn)證身份過程中,會(huì)判斷是否過了有效期的一半,要是的話更新一次cookie的有效期;若是持久cookie,Expiration屬性無意義,這時(shí)身份驗(yàn)證票的有效期有cookie的Expires決定,RedirectFromLoginPage方法給Expires屬性設(shè)定的是50年有效期;
strCookiePath: 標(biāo)示將生成的Cookie的寫到客戶端的路徑,身份驗(yàn)證票中保存這個(gè)路徑是在刷新身份驗(yàn)證票Cookie時(shí)使用(這也是生成Cookie的Path),若沒有strCookiePath 參數(shù),則使用web.config中 path屬性的設(shè)置。
這里可以看到,此方法參數(shù)只有三個(gè),而身份驗(yàn)證票的屬性有七個(gè),不足的四個(gè)參數(shù)是這么來的:
IssueDate: Cookie發(fā)出時(shí)間由當(dāng)前時(shí)間得出;
Expiration:過期時(shí)間由當(dāng)前時(shí)間和下面要說的<Forms>標(biāo)簽中timeout參數(shù)算出。此參數(shù)對(duì)非持久性cookie有意義;
UserData: 這個(gè)屬性可以用應(yīng)用程序?qū)懭胍恍┯脩舳x的數(shù)據(jù),此方法沒有用到這個(gè)屬性,只是簡單的將此屬性置為空字符串,請(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年以后過期;若是非持久cookie,Expires屬性不設(shè)置。
生成身份驗(yàn)證Cookie后,將此Cookie加入到Response.Cookies中,等待發(fā)送到客戶端。最后RedirectFromLoginPage方法調(diào)用FormsAuthentication.GetRedirectUrl 方法獲取到用戶原先請(qǐng)求的頁面,重定向到這個(gè)頁面。
(3) <Forms>標(biāo)簽中的timeout和path,是提供了身份驗(yàn)證票寫入到Cookie過期時(shí)間和默認(rèn)路徑。
經(jīng)過上面的幾步,就完成了基于窗體身份驗(yàn)證的過程。基于窗體的身份驗(yàn)證使用的時(shí)是非常靈活的 ,在實(shí)際應(yīng)用中可以根據(jù)用戶身份進(jìn)行授權(quán)管理,包括基于角色的用戶權(quán)限管理等。下面一節(jié)中,我們來介紹基于Windows的身份驗(yàn)證。
下面這個(gè)實(shí)例演示了如何利用窗體驗(yàn)證來實(shí)現(xiàn)ASP.NET的安全控制的。實(shí)例是在我們前面已經(jīng)建立好的MyFirst應(yīng)用程序中完成的,該Web應(yīng)用程序包含兩個(gè)Web窗體,一個(gè)是index.aspx,代表默認(rèn)主頁,一個(gè)是Login.aspx,代表用戶登錄系統(tǒng)頁面。
首先是Web.config配置文件,如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation defaultLanguage="vb" debug="true" />
<customErrors mode="RemoteOnly" />
<authentication mode="Forms">
<forms name=".ASPXAUTH" loginUrl="Login.aspx" timeout="30"></forms>
</authentication>
<authorization>
<deny users="admin2" />
<deny users="?" />
</authorization>
<trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" />
<sessionState
mode="InProc"
stateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes"
cookieless="false"
timeout="20"
/>
<globalization requestEncoding="utf-8" responseEncoding="utf-8" />
</system.web>
</configuration>
Index.aspx的HTML代碼如下:
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="index.aspx.vb" Inherits="MyFirst.WebForm2"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<title>基于Web窗體的身份驗(yàn)證實(shí)例</title>
<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
<meta content="Visual Basic .NET 7.1" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<FONT face="宋體">
<asp:Button id="Button1" style="Z-INDEX: 101; LEFT: 112px; POSITION: absolute; TOP: 72px" runat="server"
Text="刪除Cookies"></asp:Button></FONT></form>
</body>
</HTML>


