在 ASP.NET 2.0 提供的 Membership 功能,可以很方便的制作登入验证的动作;不过有时因为特殊需求需要自行制作登入验证机制,例如制作现行构系统的 Web 前端,可能就需要呼叫中间层去执行登入验证的动作,在此提供一个登入验证机制的实作。
我们将登入验证机制包含在一个独立组件中,新的网站应用程序只需参考这个组件就可以使用登入验证机制。此组件中包的类别如下表及下图所示。
型别 | 说明 |
TUserInfo | 使用者信息。 |
TBBasePage | 页面基础类别。 |
TBLoginPage | 登入页面基础类别。 |
.TUserInfo 类别
其中 IUserInfo 接口是定义在更上层的组件中,是为了三层式架构中传递使用者信息使用,例如 Web 组件(ASP.NET)传递到中间层组件(.NET)使用,当然在这个案例中,你也可以直接定义 TUserInfo 类别即可。
TUserInfo 类别的程序代码如下,此案例中只会使用到 IsLogin 属性。
1: Public Class TUserInfo
2: Implements IUserInfo
3:
4: Private FID As String = String.Empty
5: Private FName As String = String.Empty
6: Private FGuid As Guid = Guid.Empty
7: Private FHandle As Integer = 0
8: Private FSessionID As String = String.Empty
9: Private FIsLogin As Boolean = False
10:
11: ''' <summary>
12: ''' 建构函式。
13: ''' </summary>
14: Sub New()
15: FGuid = Guid.NewGuid()
16: End Sub
17:
18: ''' <summary>
19: ''' 使用者账号。
20: ''' </summary>
21: Public Property ID() As String Implements IUserInfo.ID
22: Get
23: Return FID
24: End Get
25: Set(ByVal value As String)
26: FID = value
27: End Set
28: End Property
29:
30: ''' <summary>
31: ''' 使用者名称。
32: ''' </summary>
33: Public Property Name() As String Implements IUserInfo.Name
34: Get
35: Return FName
36: End Get
37: Set(ByVal value As String)
38: FName = value
39: End Set
40: End Property
41:
42: ''' <summary>
43: ''' 执行阶段使用者识别码。
44: ''' </summary>
45: Public Property Guid() As System.Guid Implements IUserInfo.Guid
46: Get
47: Return FGuid
48: End Get
49: Set(ByVal value As System.Guid)
50: FGuid = value
51: End Set
52: End Property
53:
54: ''' <summary>
55: ''' 执行阶段使用者识别句柄。
56: ''' </summary>
57: Public Property Handle() As Integer Implements IUserInfo.Handle
58: Get
59: Return FHandle
60: End Get
61: Set(ByVal value As Integer)
62: FHandle = value
63: End Set
64: End Property
65:
66: ''' <summary>
67: ''' 执行阶段使用者标识符串。
68: ''' </summary>
69: Public Property SessionID() As String Implements IUserInfo.SessionID
70: Get
71: Return FSessionID
72: End Get
73: Set(ByVal value As String)
74: FSessionID = value
75: End Set
76: End Property
77:
78: ''' <summary>
79: ''' 是否已登入。
80: ''' </summary>
81: Public Property IsLogin() As Boolean Implements IUserInfo.IsLogin
82: Get
83: Return FIsLogin
84: End Get
85: Set(ByVal value As Boolean)
86: FIsLogin = value
87: End Set
88: End Property
89: End Class
.TBBasePage 类别
TBBasePage 是页面基础类别,主要做判断是否登入,若未登入则转址到定义的登入页面。TBBasePage 类别的主要属性如下表所示。
属性 | 说明 |
IsCheckLogin | 是否做登入验证,预设为 True。
继承 TBBasePage 的页面预设是需要做登入验证的,若有页面不需做登入验证(如登入页面),则需要覆写此属性传回 False。 |
LoginUrl | 登入页面网址。
预设是读取 web.config 中 appSettings 区段的 LoginUrl 参数值。你也可以覆写此属性,改写登入页面网址的定义方式。 |
UserInfo | 使用者信息。此属性是储存于 Seesion 中。 |
TBBasePage 类别的完整程序代码如下所示,其中覆写 OnInit 方法,判断此页面是否做登入验证;若需要做登入验证时,则使用 UserInfo.IsLogin 来判断是否已登入,若未登入则转址到 LoginUrl 属性指定的登入页面网址。
1: Imports Bee.App
2:
3: ''' <summary>
4: ''' 页面基础类别。
5: ''' </summary>
6: Public Class TBBasePage
7: Inherits System.Web.UI.Page
8:
9: Private Const KEY_USERINFO As String = "_UserInfo"
10: Private FUserInfo As TUserInfo = Nothing
11:
12:
13: ''' <summary>
14: ''' 是否做登入验证。
15: ''' </summary>
16: Protected Overridable ReadOnly Property IsCheckLogin() As Boolean
17: Get
18: Return True
19: End Get
20: End Property
21:
22: ''' <summary>
23: ''' 取得 Web.config 中 appSettings 区段定义的参数。
24: ''' </summary>
25: Public Overloads Function AppSettings(ByVal Name As String) As String
26: Return AppSettings(Name, String.Empty)
27: End Function
28:
29: ''' <summary>
30: ''' 取得 Web.config 中 appSettings 区段定义的参数。
31: ''' </summary>
32: Public Overloads Function AppSettings(ByVal Name As String, ByVal DefaultValue As String) As String
33: Dim sValue As String
34:
35: sValue = System.Web.Configuration.WebConfigurationManager.AppSettings(Name)
36: If sValue Is Nothing Then
37: Return DefaultValue
38: Else
39: Return sValue
40: End If
41: End Function
42:
43: ''' <summary>
44: ''' 登入页面网址。
45: ''' </summary>
46: Public Overridable ReadOnly Property LoginUrl() As String
47: Get
48: Dim sUrl As String
49: sUrl = Me.AppSettings("LoginUrl")
50: If String.IsNullOrEmpty(sUrl) Then
51: Throw New Exception("未设定登入页面")
52: Else
53: Return sUrl
54: End If
55: End Get
56: End Property
57:
58: ''' <summary>
59: ''' 使用者信息。
60: ''' </summary>
61: Public ReadOnly Property UserInfo() As TUserInfo
62: Get
63: If FUserInfo Is Nothing Then
64: If Me.Session(KEY_USERINFO) Is Nothing Then
65: FUserInfo = New TUserInfo()
66: Me.Session(KEY_USERINFO) = FUserInfo
67: Else
68: FUserInfo = CType(Me.Session(KEY_USERINFO), TUserInfo)
69: End If
70: End If
71: Return FUserInfo
72: End Get
73: End Property
74:
75: Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
76: '判断是否做登入验证
77: If Me.IsCheckLogin Then
78: '判断是否登入,若未登入则转址到登入页面
79: If Not Me.UserInfo.IsLogin Then
80: Page.Response.Redirect(Me.LoginUrl)
81: End If
82: End If
83:
84: MyBase.OnInit(e)
85: End Sub
86: End Class
.TBLoginPage 类别
TBLoginPage 类别是登入页面基础类别。TBLoginPage 类别是继承 TBBasePage 类别,因为它是登入页面所需无须做登入验证,所以覆写 IsCheckLogin 方法传回 False。自行撰写的登入页面可以继承 TBLoginPage 类别,并覆写 ExecuteLogin 方法实作登入验证的动作;按下登入钮时,则是呼叫 Login 方法来进行登入。
1: ''' <summary>
2: ''' 登入页面基础类别。
3: ''' </summary>
4: Public MustInherit Class TBLoginPage
5: Inherits TBBasePage
6:
7: ''' <summary>
8: ''' 是否做登入验证。
9: ''' </summary>
10: Protected Overrides ReadOnly Property IsCheckLogin() As Boolean
11: Get
12: Return False
13: End Get
14: End Property
15:
16: ''' <summary>
17: ''' 执行登入验证,衍生类别必须覆写。
18: ''' </summary>
19: ''' <param name="UserID">登入账号。</param>
20: ''' <param name="Password">登入密码。</param>
21: ''' <returns>登入成功传回 Treu,反之传回 False。</returns>
22: Protected MustOverride Function ExecuteLogin(ByVal UserID As String, ByVal Password As String) As Boolean
23:
24: ''' <summary>
25: ''' 执行登入。
26: ''' </summary>
27: ''' <param name="UserID">登入账号。</param>
28: ''' <param name="Password">登入密码。</param>
29: Protected Overridable Sub Login(ByVal UserID As String, ByVal Password As String)
30: If ExecuteLogin(UserID, Password) Then
31: Me.UserInfo.IsLogin = True
32: Me.Response.Redirect("~/")
33: Else
34: Me.ClientScript.RegisterStartupScript(Me.GetType, "LoginError", "alert('登入错误');", True)
35: End If
36: End Sub
37:
38: End Class
.撰写 ASP.NET 网站应用程序测试登入
再来新增一个新的 ASP.NET 网站应用程序,首先在其 web.config 中定义登入页面网址为 "~/Login.aspx"。
<appSettings>
<add key="LoginUrl" value="~/Login.aspx"/>
</appSettings>
撰写登入网页命名为 Login.aspx,此页面继承 TBLoginPage 类别,并覆写 ExecuteLogin 方法。在此做登入测试,故在 ExecuteLogin 方法中只判断登入账号/密码为 admin/admin 时即传回 True,表示登入成功。实际使用时可以在此方法自行连结数据库或呼叫中间层做身份认识的动作。当按下「登入」钮时,只需呼叫 TBLoginPage 的 Login 方法传入账号/密码即可。
在网站中任何新增的页面只要继承 TBBasePage,当使用者浏览该网页时,就会由机制处理登入验证的动作,无需在页面做相关控管。
Login.aspx 程序代码
1: <%@ Page Language="VB" AutoEventWireup="false" CodeFile="Login.aspx.vb" Inherits="Login" %>
2:
3: <html xmlns="http://www.w3.org/1999/xhtml">
4: <head runat="server">
5: <title>未命名页面</title>
6: </head>
7: <body>
8: <form id="form1" runat="server">
9: <div>
10: <table align="center" style="border: #0066cc solid 1px" border="1">
11: <tr>
12: <td align="center" colspan="3" style="height: 20px; color: white; background-color: #3366cc">
13: 登入</td>
14: </tr>
15: <tr>
16: <td align="center" style="width: 83px; height: 17px; text-align: right;">
17: 账号
18: </td>
19: <td align="center" style="height: 17px; text-align: left; width: 209px;">
20: <asp:TextBox ID="txtLoginID" runat="server" Width="200px" AutoCompleteType="Disabled"
21: CssClass="username"></asp:TextBox></td>
22: </tr>
23: <tr>
24: <td align="center" style="width: 83px; height: 21px; text-align: right;">
25: 密码
26: </td>
27: <td align="center" style="height: 21px; text-align: left; width: 209px;">
28: <asp:TextBox ID="txtLoginPwd" runat="server" Width="200px" TextMode="Password" AutoCompleteType="Disabled"
29: EnableViewState="False" CssClass="password"></asp:TextBox></td>
30: </tr>
31: <tr>
32: <td colspan="3" style="text-align: right; vertical-align: text-bottom; height: 30px;">
33: <asp:Button ID="btnLogin" runat="server" Text="登入" />
34: </td>
35: </tr>
36: </table>
37: </div>
38: </form>
39: </body>
40: </html>
Login.aspx.vb
1: Partial Class Login
2: Inherits Bee.Web.TBLoginPage
3:
4: ''' <summary>
5: ''' 执行登入验证。
6: ''' </summary>
7: ''' <param name="UserID">登入账号。</param>
8: ''' <param name="Password">登入密码。</param>
9: ''' <returns>登入成功传回 Treu,反之传回 False。</returns>
10: Protected Overrides Function ExecuteLogin(ByVal UserID As String, ByVal Password As String) As Boolean
11: If UserID = "admin" AndAlso Password = "admin" Then
12: Return True
13: Else
14: Return False
15: End If
16: End Function
17:
18: Protected Sub btnLogin_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnLogin.Click
19: Me.Login(txtLoginID.Text, txtLoginPwd.Text)
20: End Sub
21: End Class