簡介
本文的第二部分主要是介紹如何使用asp.net實現我們自己的表格認證的方法。在第一部分中,我們討論了表格認證的基本概念和原理。在閱讀本文的第二部分之前,讀者需要了解表格認證的一些基本概念,或者已經閱讀過第一部分。
自定義表格認證的建立
使用的頁面:default.aspx、login.aspx、web.config、users.xml、hashpassword.aspx
在這個自定義表格認證的例子中,我們將自始至終地使用一個xml文檔存儲用戶名和口令。建立該自定義表格認證所需要的一些準備工作:
- 在互聯網服務器的根目錄下建立名字為customforms的目錄。
- 使該文件夾成為互聯網服務管理器中的一個應用。
- 創建名字為unsecure的子目錄。
- 創建名字為hashpassword.aspx的文件,并將它移到unsecure目錄。
web.config概覽
web.config文件中包含了web應用程序的所有可配置的設置選項。我加亮顯示了需要認真研究的代碼:
web.config代碼
<configuration>
<system.web>
<customerrors mode="off"/>
<authentication mode="forms">
<forms name="authcookie" path="/" loginurl="login.aspx" protection="all" timeout="10">
</forms>
</authentication>
<authorization>
<deny users="?" />
</authorization>
</system.web>
這部分加亮顯示
<location path="unsecure">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
這部分加亮顯示
</configuration>
web.config詳解
這個例子增加了一個名字為location的配置小節,它允許我們覆蓋web.config文件中system.web配置小節的設置。在本例中,我們希望允許匿名或沒有通過認證的用戶訪問unsecure目錄,常見的例子是整個web應用都是安全的,只有注冊頁是個例外。通過允許匿名用戶訪問一個目錄,我們可以將能夠被任何人瀏覽的文件存儲到該目錄中。如果有必要,我們可以創建多個location小節。
users.xml概覽
在這個文件中,我們存儲了所有認證需要的數據,例如用戶名和口令。口令采用了sha1算法進行加密,稍后我們會對sha1算法進行解釋。
users.xml代碼
<?xml version="1.0"?>
<users>
<jeff>a94a8fe5ccb19ba61c4c0873d391e987982fbbd3</jeff>
<mike>a94a8fe5ccb19ba61c4c0873d391e987982fbbd3</mike>
</users>
users.xml詳解
在該文件中,有一個被稱作users的小節,其中包含有每個用戶的個人節點,在節點的開始、結束標志之間,有一個經過哈希處理的口令。很明顯的是,該文件中也可以包含更多的信息,例如姓、名以及電話號碼等。
login.aspx概覽
該文件包含對一個用戶進行認證所需要的全部邏輯。在本例中,我們將使用一個xml文件對用戶進行認證,當然了我們也可以將本頁的邏輯用于使用一個數據庫對用戶進行認證。
login.aspx代碼
<%@page language="vb" %>
<%@import namespace="system.web.security" %>
<%@import namespace="system.xml" %>
<script language="vb" runat="server">
sub processlogin(objsender as object, objargs as eventargs)
dim strcurrentpath as string = request.physicalpath
dim strxmldocpath as string = left(strcurrentpath, instrrev(strcurrentpath, "/")) & "users.xml"
dim struser as string = txtuser.text
dim strpassword as string = txtpassword.text
dim strencpassword as string = gethashedpass(strpassword)
dim blnisauthenticated as boolean
dim objxmldoc as new xmldocument()
try
objxmldoc.load(strxmldocpath)
catch objerror as exception
errormessage.innerhtml = "<b> the xml document could not be loaded.</b>.<br>" & _
objerror.message & "<br />" & objerror.source
exit sub
end try
dim usernodes as xmlnodelist
usernodes = objxmldoc.getelementsbytagname(struser)
是否有用戶名與輸入的用戶名相同的元素
if not usernodes is nothing then
dim blnuserexists as boolean = true
dim strusercheck as string
try
strusercheck = usernodes(0).firstchild().value
catch objerror as exception
errormessage.innerhtml = "<b>invalid username</b> please re-enter..."
blnuserexists = false
end try
if blnuserexists = true then
if strencpassword = usernodes(0).firstchild().value then
blnisauthenticated = true
else
errormessage.innerhtml = "<b>invalid password</b> please re-enter..."
end if
end if
end if
if blnisauthenticated then
formsauthentication.redirectfromloginpage(struser, chkpersistlogin.checked)
end if
end sub
function gethashedpass(byval apassword as string) as string
return formsauthentication.hashpasswordforstoringinconfigfile(apassword,"sha1")
end function
</script>
<html>
<head>
<title>custom forms authentication login form</title>
</head>
<body bgcolor="#ffffff" text="#000000">
<form runat="server">
<table width="400" border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="80">username : </td>
<td width="10"> </td>
<td><asp:textbox id="txtuser" runat="server"/></td>
</tr>
<tr>
<td>password : </td>
<td width="10"> </td>
<td><asp:textbox id="txtpassword" textmode="password" runat="server"/></td>
</tr>
<tr>
<tr>
<td></td>
<td width="10"> </td>
<td><asp:checkbox id="chkpersistlogin" runat="server" />remember my credentials
<br>
</td>
</tr>
<tr>
<td> </td>
<td width="10"> </td>
<td><asp:button id="cmdlogin" onclick="processlogin" text="login" runat="server" /></td>
</tr>
</table>
<br>
<br>
<div id="errormessage" runat="server" />
</form>
</body>
</html>
login.aspx詳解
在本例中,我添加了對system.web.security和system.xml的引用,因為我們將會用到這二個名字空間中的類。我們還編寫了一個名字為processlogin的過程,它的作用是檢查表格數據(用戶名和口令)與xml文件中所包含的口令和用戶名是否相同。
首先,我們為文本編輯框創建了一些局部變量。由于需要得到users.xml文件的全路徑,因此我們使用了
request.physicalpath方法,然后對腳本文件名進行整理。另外我們還創建了一個變量,保存經過哈希處理后的口令。
其次,我們將xmldoc.load方法調用放在try...catch語句中。try...catch語句是asp.net中新增添的,它是處理錯誤和異常的一種很好的方式。在下面的代碼,我們將用戶節點表作為一個變量數組,使用getelementsbytagname方法將xml文件中的用戶節點賦給它。然后檢查該用戶是否存在,如果存在,則檢查用戶輸入的口令是否與存儲在xml文件中的相同。如果用戶存在,而且口令也相同,我們就將blnisauthenticated的值勤設置為true。在過程的末尾,如果blnisauthenticated的值為true,我們就調用redirectfromloginpage方法。當然了,我們也可以使用setauthcookie方法來完成同樣的功能,但不會把用戶引導到另一個網頁。
在login.aspx文件的接口或html部分,我們有開發了2個服務器端正文框,1個服務器端復選框,1個按鈕,在該按鈕的onclick事件中,調用了processlogin。我們還有一個在服務器端運行的div,它能夠向用戶顯示出錯信息。
default.aspx概覽
該文件中的代碼與本篇文章第一部分的default.aspx文件相同。
default.aspx的代碼
<%@page language="vb" %>
<%@import namespace="system.web.security" %>
<script language="vb" runat="server">
sub signout(objsender as object, objargs as eventargs)
刪除用戶認證的cookie并退出
formsauthentication.signout()
將用戶引導到提交的網頁
response.redirect(request.urlreferrer.tostring())
end sub
sub page_load()
驗證認證
if user.identity.isauthenticated then
顯示認證信息
displaycredentials.innerhtml = "current user : <b>" & user.identity.name & _
"</b><br><br>authentication used : <b>" & _
user.identity.authenticationtype & "</b>"
else
顯示錯誤信息
displaycredentials.innerhtml = "sorry, you have not been authenticated."
cmdsignout.disabled = true
end if
end sub
</script>
<html>
<head>
<title>forms authentication</title>
</head>
<body bgcolor="#ffffff" text="#000000">
<span class="header">forms based authentication using custom method</span>
<br>
<br>
<div id="displaycredentials" runat="server" />
<br>
<br>
<form runat="server">
<input id="cmdsignout" type="submit" value="sign out" runat="server" onserverclick="signout" /><p />
</form>
</body>
</html>
default.aspx詳解
該網頁與本文第一部分中的default.aspx的功能完全相同,它只是簡單地顯示用戶名和使用的認證方法。
hashpassword.aspx概覽
這個網頁允許一個未經認證的用戶創建加密的口令,它可以用于在web.config的credentials小節、xml文件或數據庫中存儲口令。
<ccid_nobr><b>hashpassword.aspx代碼</b></ccid_nobr>
<%@page language="vb" %>
<%@import namespace="system.web.security" %>
<script language="vb" runat="server">
sub gethashedpass(objsender as object, objargs as eventargs)
dim strencpass as string
strencpass = formsauthentication.hashpasswordforstoringinconfigfile(txtpassword.value,"sha1")
hashedpass.innerhtml = "hashed password for web.config, xml file or database<br><b>" & _
strencpass & "</b>"
end sub
</script>
<html>
<head>
<title>create hashed password</title>
</head>
<body bgcolor="#ffffff" text="#000000">
<b>create hashed password</b>
<form runat="server">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td>password to encrypt:
<input id="txtpassword" type="password" runat="server" name="text"/>
<input type="submit" value="hash pass" runat="server" onserverclick="gethashedpass"/>
</td>
</tr>
<tr>
<tr>
<td> </td>
</tr>
<tr>
<td>
<div id="hashedpass" runat="server"/>
</td>
</tr>
</table>
</form>
</body>
</html>
hashpassword.aspx詳解
為了使用forms authentication名字空間,我們需要再次使用system.web.security名字空間。這里,我們使用一個過程接收文本框的文本,并使用sha1哈希算法對它進行哈希處理。完成這一功能的方法的名字是hashpasswordforstoringinconfigfile(這很可能是我看到的最長的方法名字了),該方法接收二個參數,一個是需要進行哈希處理的字符串,另一個是要使用的算法,在該方法中,我們可以使用sha1或md5算法。
結束語
就象在上面的稿子中看到的那樣,在web應用程序的開發中,表格認證是一個功能強大的工具。如果能夠掌握好它的使用,會給我們的開發工作帶來很大的方便。
注冊會員,創建你的web開發資料庫,