本文介绍如何通过使用数据库存储用户来实现基于窗体的身份验
要求
下表列出了推荐使用的硬件、软件、网络架构以及所需的 Service Pack:
- Microsoft Visual Studio .NET
- Microsoft Internet 信息服务 (IIS) 5.0 或更高版本
- Microsoft SQL Server
使用 C# .NET 创建 ASP.NET 应用程序
- 打开 Visual Studio .NET。
- 新建 ASP.NET Web 应用程序,并指定应用程序的名称和位置。
在 Web.config 文件中配置安全设置
本节介绍如何添加和修改 <authentication> 和 <authorization> 配置部分,以便将 ASP.NET 应用程序配置为使用基于窗体的身份验证。
- 在解决方案资源管理器中,打开 Web.config 文件。
- 将身份验证模式更改为 Forms(窗体)。
- 插入 <Forms> 标记,并填入相应的属性。(有关这些属性的更多信息,请参考 MSDN 文档或快速入门文档,这些文档在 参考 一节中列出。)复制以下代码,然后在“编辑”菜单中单击“粘贴为 HTML”,将该代码粘贴到文件的 <authentication> 部分:
<authentication mode="Forms"> <forms name=".ASPXFORMSDEMO" loginUrl="logon.aspx" protection="All" path="/" timeout="30" /> </authentication>
- 在 <authorization> 部分中拒绝匿名用户的访问(如下所示):
<authorization> <deny users ="?" /> <allow users = "*" /> </authorization>
创建示例数据库表以存储用户详细信息
本节介绍如何创建可存储用户名、密码和用户角色的示例数据库。如果要将用户角色存储在数据库中并实现基于角色的安全性,则需要角色列。
- 在“开始”菜单上,单击“运行”,然后键入 notepad 以打开记事本。
- 突出显示以下 SQL 脚本代码,右键单击该代码,然后单击“复制”。在记事本中,单击“编辑”菜单上的“粘贴”以粘贴以下代码:
if exists (select * from sysobjects where id = object_id(N [dbo].[Users] ) and OBJECTPROPERTY(id, N IsUserTable ) = 1) drop table [dbo].[Users] GO CREATE TABLE [dbo].[Users] ( [uname] [varchar] (15) NOT NULL , [Pwd] [varchar] (25) NOT NULL , [userRole] [varchar] (25) NOT NULL , ) ON [PRIMARY] GO ALTER TABLE [dbo].[Users] WITH NOCHECK ADD CONSTRAINT [PK_Users] PRIMARY KEY NONCLUSTERED ( [uname] ) ON [PRIMARY] GO INSERT INTO Users values( user1 , user1 , Manager ) INSERT INTO Users values( user2 , user2 , Admin ) INSERT INTO Users values( user3 , user3 , User ) GO
- 将该文件另存为 Users.sql。
- 在 Microsoft SQL Server 计算机上,在查询分析器中打开 Users.sql。在数据库列表中,单击“pubs”,然后运行该脚本。这将创建一个示例用户表,并使用此示例应用程序填充要使用的 Pubs 数据库中的该表。
创建 Logon.aspx 页
- 将一个新的 Web 窗体添加到名为 Logon.aspx 的项目中。
- 在编辑器中打开 Logon.aspx 页,并切换到 HTML 视图。
- 复制以下代码,然后使用“编辑”菜单上的“粘贴为 HTML”选项将代码插入到 <form> 标记之间:
<h3> <font face="Verdana">Logon Page</font> </h3> <table> <tr> <td>Email:</td> <td><input id="txtUserName" type="text" runat="server"></td> <td><ASP:RequiredFieldValidator ControlToValidate="txtUserName" Display="Static" ErrorMessage="*" runat="server" ID="vUserName" /></td> </tr> <tr> <td>Password:</td> <td><input id="txtUserPass" type="password" runat="server"></td> <td><ASP:RequiredFieldValidator ControlToValidate="txtUserPass" Display="Static" ErrorMessage="*" runat="server" ID="vUserPass" /> </td> </tr> <tr> <td>Persistent Cookie:</td> <td><ASP:CheckBox id="chkPersistCookie" runat="server" autopostback="false" /></td> <td></td> </tr> </table> <input type="submit" Value="Logon" runat="server" ID="cmdLogin"><p></p> <asp:Label id="lblMsg" ForeColor="red" Font-Name="Verdana" Font-Size="10" runat="server" />
- 切换到“设计”视图并保存该页。
对事件处理程序进行编码以使它验证用户凭据
本节给出位于代码隐藏页 (Logon.aspx.cs) 中的代码。
- 双击“Logon”打开 Logon.aspx.cs 文件。
- 导入代码隐藏文件中必需的命名空间:
using System.Data.SqlClient; using System.Web.Security;
- 创建 ValidateUser 函数,以便通过查找数据库来验证用户凭据。(确保将连接字符串更改为指向数据库。)
private bool ValidateUser( string userName, string passWord ) { SqlConnection conn; SqlCommand cmd; string lookupPassword = null; // Check for invalid userName. // userName must not be null and must be between 1 and 15 characters. if ( ( null == userName ) || ( 0 == userName.Length ) || ( userName.Length > 15 ) ) { System.Diagnostics.Trace.WriteLine( "[ValidateUser] Input validation of userName failed." ); return false; } // Check for invalid passWord. // passWord must not be null and must be between 1 and 25 characters. if ( ( null == passWord ) || ( 0 == passWord.Length ) || ( passWord.Length > 25 ) ) { System.Diagnostics.Trace.WriteLine( "[ValidateUser] Input validation of passWord failed." ); return false; } try { // Consult with your SQL Server administrator for an appropriate connection // string to use to connect to your local SQL Server. conn = new SqlConnection( "server=localhost;Integrated Security=SSPI;database=pubs" ); conn.Open(); // Create SqlCommand to select pwd field from users table given supplied userName. cmd = new SqlCommand( "Select pwd from users where uname=@userName", conn ); cmd.Parameters.Add( "@userName", SqlDbType.VarChar, 25 ); cmd.Parameters["@userName"].Value = userName; // Execute command and fetch pwd field into lookupPassword string. lookupPassword = (string) cmd.ExecuteScalar(); // Cleanup command and connection objects. cmd.Dispose(); conn.Dispose(); } catch ( Exception ex ) { // Add error handling here for debugging. // This error message should not be sent back to the caller. System.Diagnostics.Trace.WriteLine( "[ValidateUser] Exception " + ex.Message ); } // If no password found, return false. if ( null == lookupPassword ) { // You could write failed login attempts here to event log for additional security. return false; } // Compare lookupPassword and input passWord, using a case-sensitive comparison. return ( 0 == string.Compare( lookupPassword, passWord, false ) ); }
- 可使用两种方法之一生成窗体身份验证 Cookie,并将用户重定向到 cmdLogin_ServerClick 事件中的相应页。为两种情形都提供了示例代码。可根据需要使用其中的一个。
- 调用 RedirectFromLoginPage 方法,以便自动生成窗体身份验证 Cookie,并将用户重定向到 cmdLogin_ServerClick 事件中的相应页:
private void cmdLogin_ServerClick(object sender, System.EventArgs e) { if (ValidateUser(txtUserName.Value,txtUserPass.Value) ) FormsAuthentication.RedirectFromLoginPage(txtUserName.Value, chkPersistCookie.Checked); else Response.Redirect("logon.aspx", true); }
- 生成身份验证票证,对其进行加密,创建 Cookie,将其添加到响应中并重定向用户。这样,您就可以更好地控制 Cookie 的创建方式了。在本例中还可以包括自定义数据和 FormsAuthenticationTicket。
private void cmdLogin_ServerClick(object sender, System.EventArgs e) { if (ValidateUser(txtUserName.Value,txtUserPass.Value) ) { FormsAuthenticationTicket tkt; string cookiestr; HttpCookie ck; tkt = new FormsAuthenticationTicket(1, txtUserName.Value, DateTime.Now, DateTime.Now.AddMinutes(30), chkPersistCookie.Checked, "your custom data"); cookiestr = FormsAuthentication.Encrypt(tkt); ck = new HttpCookie(FormsAuthentication.FormsCookieName, cookiestr); if (chkPersistCookie.Checked) ck.Expires=tkt.Expiration; ck.Path = FormsAuthentication.FormsCookiePath; Response.Cookies.Add(ck); string strRedirect; strRedirect = Request["ReturnUrl"]; if (strRedirect==null) strRedirect = "default.aspx"; Response.Redirect(strRedirect, true); } else Response.Redirect("logon.aspx", true); }
- 调用 RedirectFromLoginPage 方法,以便自动生成窗体身份验证 Cookie,并将用户重定向到 cmdLogin_ServerClick 事件中的相应页:
- 确保将以下代码添加到由 Web 窗体设计器生成的代码的 InitializeComponent 方法中。
this.cmdLogin.ServerClick += new System.EventHandler(this.cmdLogin_ServerClick);
创建 Default.aspx 页
本节创建一个测试页,用户经过身份验证后将重定向到该页。如果用户在没有先登录到应用程序的情况下浏览此页,则将他们重定向到登录页。
- 将现有 WebForm1.aspx 页重命名为 Default.aspx,并在编辑器中打开它。
- 切换到 HTML 视图,并将下面的代码复制到 <form> 标记之间:
<input type="submit" Value="SignOut" runat="server" id="cmdSignOut">
- 切换到“设计”视图并保存该页。
- 导入代码隐藏文件中必需的命名空间:
using System.Web.Security;
- 双击 SignOut 打开代码隐藏页 (Default.aspx.cs),将以下代码复制到 cmdSignOut_ServerClick 事件处理程序中:
private void cmdSignOut_ServerClick(object sender, System.EventArgs e) { FormsAuthentication.SignOut(); Response.Redirect("logon.aspx", true); }
- 确保将以下代码添加到由 Web 窗体设计器生成的代码的 InitializeComponent 方法中。
this.cmdSignOut.ServerClick += new System.EventHandler(this.cmdSignOut_ServerClick);
- 保存并编译项目。现在,您就可以使用该应用程序了。
相关新闻
- 小程序登录流程图理解 2020-08-18
- 在C#中获取web.config中的配置信息 2021-08-23
- 小程序open-data头像样式 2021-04-10
- 小程序rich-text 富文本解析图片过大和图片路径的问题 2020-11-25
- C#中去掉字符串的最后一个字符 2020-11-23