asp.net
簡介
本文的第二部分主要是介紹如何使用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" 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應用程式的開發中,表格認證是一個功能強大的工具。如果能夠掌握好它的使用,會給我們的開發工作帶來很大的方便。