如何使用 C# .NET 在 ASP.NET 应用程序中实现基于窗体的身份验证

作者:微软 本文的发布号曾为 CHS301240
有关本文的 Microsoft Visual Basic .NET 版本,请参阅 308157。

在 Web.config 文件中配置安全设置
本节介绍如何添加和修改 authentication
和 authorization
配置部分,以便将 ASP.NET 应用程序配置为使用基于窗体的身份验证。 1.
在项目资源管理器中,打开 Web.config 文件。

2.
将身份验证模式更改为Forms
(窗体)。

3.
插入 Forms 标记,并填入相应的属性。(有关这些属性的更多信息,请参阅 参考
一节中列出的 MSDN 文档或快速入门文档。)复制以下代码,然后单击编辑菜单上的粘贴为 HTML,以粘贴文件 authentication
部分中的代码: authentication mode=Forms forms name=.ASPXFORMSDEMO loginUrl=logon.aspx protection=All path=/ timeout=30 / /authentication



4.
在 authorization
部分中拒绝匿名用户的访问(如下所示): authorization deny users =? / allow users = * / /authorization




返回页首
创建示例数据库表以存储用户详细信息
本节介绍如何创建可存储用户名、密码和用户角色的示例数据库。如果要将用户角色存储在数据库中并实现基于角色的安全性,则需要角色列。 1.
在开始菜单上,单击运行,然后键入 notepad 以打开记事本。

2.
突出显示以下 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



3.
将该文件另存为 Users.sql。

4.
在 Microsoft SQL Server 计算机上,在查询分析器中打开 Users.sql。在数据库列表中,单击pubs,然后运行该脚本。这将创建一个示例用户表,并使用此示例应用程序填充要使用的 Pubs 数据库中的该表。


返回页首
创建 Logon.aspx 页
1.
将一个新的 Web 窗体添加到名为 Logon.aspx 的项目中。

2.
在编辑器中打开 Logon.aspx 页,并切换到 HTML 视图。

3.
复制以下代码,然后使用编辑菜单上的粘贴为 HTML选项将代码插入到 form 标记之间: h3 font face=VerdanaLogon Page/font /h3 table tr tdEmail:/td tdinput id=txtUserName type=text runat=server/td tdASP:RequiredFieldValidator ControlToValidate=txtUserName Display=Static ErrorMessage=* runat=server ID=vUserName //td /tr tr tdPassword:/td tdinput id=txtUserPass type=password runat=server/td tdASP:RequiredFieldValidator ControlToValidate=txtUserPass Display=Static ErrorMessage=* runat=server ID=vUserPass / /td /tr tr tdPersistent Cookie:/td tdASP:CheckBox id=chkPersistCookie runat=server autopostback=false //td td/td /tr /table input type=submit Value=Logon runat=server ID=cmdLoginp/p asp:Label id=lblMsg ForeColor=red Font-Name=Verdana Font-Size=10 runat=server /

此 Web 窗体用于向用户提供登录窗体,以便他们提供用于登录到应用程序的用户名和密码。


4.
切换到设计视图并保存该页。


返回页首
对事件处理程序进行编码以使它验证用户凭据
本节给出位于代码隐藏页 (Logon.aspx.cs) 中的代码。 1.
双击Logon打开 Logon.aspx.cs 文件。

2.
导入代码隐藏文件中必需的命名空间: using System.Data.SqlClient; using System.Web.Security;



3.
创建 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 ) ); }



4.
可使用两种方法之一生成窗体身份验证 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); }






5.
确保将以下代码添加到由 Web 窗体设计器生成的代码的 InitializeComponent
方法中。 this.cmdLogin.ServerClick += new System.EventHandler(this.cmdLogin_ServerClick);




返回页首
创建 Default.aspx 页
本节创建一个测试页,用户经过身份验证后将重定向到该页。如果用户在没有先登录到应用程序的情况下浏览此页,则将他们重定向到登录页。 1.
将现有 WebForm1.aspx 页重命名为 Default.aspx,并在编辑器中打开它。

2.
切换到 HTML 视图,并将下面的代码复制到 form 标记之间: input type=submit Value=SignOut runat=server id=cmdSignOut

此按钮用于注销窗体身份验证会话。


3.
切换到设计视图并保存该页。

4.
导入代码隐藏文件中必需的命名空间: using System.Web.Security;



5.
双击 SignOut
打开代码隐藏页 (Default.aspx.cs),并在 cmdSignOut_ServerClick
事件处理程序中复制以下代码: private void cmdSignOut_ServerClick(object sender, System.EventArgs e) { FormsAuthentication.SignOut(); Response.Redirect(logon.aspx, true); }



6.
确保将以下代码添加到由 Web 窗体设计器生成的代码的 InitializeComponent
方法中。 this.cmdSignOut.ServerClick += new System.EventHandler(this.cmdSignOut_ServerClick);



7.
保存并编译项目。现在,您就可以使用该应用程序了。


返回页首
其他说明

您可能希望将密码安全地存储在数据库中。在将密码存储在数据库或配置文件中之前,可以使用名为 HashPasswordForStoringInConfigFile
的 FormsAuthentication
类实用工具函数对密码进行加密。


您可能希望将 SQL 连接信息存储在配置文件 (Web.config) 中,以便在需要时方便地修改它。


也可以考虑添加代码,以防黑客使用不同的密码组合进行登录。例如,可以包含一个只允许两次或三次登录尝试的逻辑。如果用户在尝试特定次数后无法登录,您可能希望在数据库中设置一个标志以禁止此用户登录,直到此用户通过访问另外一个页面或拨打您的支持电话重新启用其帐户时为止。另外,还应根据需要添加相应的错误处理代码。


因为用户是基于身份验证 Cookie 来标识的,所以您可能希望在此应用程序上使用安全套接字层 (SSL),这样任何人都无法骗取身份验证 Cookie 和传输的任何其他重要信息。


基于窗体的身份验证要求客户机在其浏览器上接受或启用 Cookie。


authentication
配置部分的 timeout
参数控制重新生成身份验证 Cookie 的时间间隔。您可以选择一个能提供较好性能和安全性的值。


Internet 上的某些中间代理和缓存可能会将包含设置 Cookie标题的 Web 服务器响应缓存起来,然后将其返回给另外一个用户。因为基于窗体身份验证使用 cookie 来验证用户身份,所以这可能导致用户通过接收到由中间代理或缓存提供的本不是要发送给他们的 cookie 而意外(或有意地)模拟另外的用户。下面这篇文章介绍如何对付这些情形: 263730
Site Server 用户可能被验证成错误的帐户



返回页首
参考
有关如何使用 credentials
部分存储用户和密码来实现基于窗体的简单身份验证的更多信息,请参阅以下 GotDotNet ASP.NET 快速入门示例: 基于窗体的身份验证
http://www.gotdotnet.com/QuickStart/aspplus/default.aspx?url=/quickstart/aspplus/doc/formsauth.aspx

有关如何使用 XML 文件存储用户和密码来实现基于窗体的身份验证的更多信息,请参阅 .NET Framework 软件开发工具包 (SDK) 文档中的以下主题: 使用 XML 用户文件的窗体身份验证
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconcookieauthenticationusinganxmlusersfile.asp

有关 ASP.NET Web 应用程序安全性的更多信息,请参阅以下 Microsoft .NET Framework 开发人员指南文档: ASP.NET Web 应用程序安全性
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconaspnetwebapplicationsecurity.asp

有关 System.Web.Security
命名空间的更多信息,请参阅以下 Microsoft .NET Framework 参考文档: System.Web.Security 命名空间
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemWebSecurity.asp

有关 ASP.NET 配置的更多信息,请参阅以下 Microsoft .NET Framework 开发人员指南文档: ASP.NET 配置
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconaspnetconfiguration.asp


ASP.NET 配置部分
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpgrfaspnetconfigurationsections.asp

有关 ASP.NET 安全指南的更多信息,请参阅以下 MSDN 白皮书: ASP.NET 中的身份验证:.NET 安全指南
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/authaspdotnet.asp

有关 ASP.NET 的更多常规信息,请访问以下 MSDN 新闻组: microsoft.public.dotnet.framework.aspnet

返回页首


这篇文章中的信息适用于:

Microsoft ASP.NET (included with the .NET Framework 1.1)


Microsoft Visual C# .NET 2003 标准版


Microsoft ASP.NET (included with the .NET Framework) 1.0


Microsoft Visual C# .NET 2002 标准版


Microsoft SQL Server 2000 标准版


Microsoft SQL Server 7.0 标准版


Microsoft SQL Server 2000 64-bit Edition





posted @ 2013-01-10 10:49  gnhao  阅读(350)  评论(0编辑  收藏  举报