您目前已離線,請等候您的網際網路重新連線

如何使用 C#.NET 在 ASP.NET 應用程式中實作表單型驗證

本文曾發行於 CHT301240
如需本文的 Microsoft Visual Basic .NET 版本,請參閱 308157.

本文參照下列 Microsoft .NET Framework 類別庫 (Class Library) 的命名空間:
  • System.Data.SqlClient
  • System.Web.Security

本文內容

結論
本文將告訴您,如何使用資料庫來實作表單型驗證,以便儲存使用者詳細資訊。

back to the top

需求

下面清單列出了建議使用的硬體、軟體、網路基礎架構以及您需要的 Service Pack:
  • Microsoft Visual Studio .NET
  • Microsoft Internet Information Services 5.0 (IIS) 或更新的版本
  • Microsoft SQL Server
back to the top

使用 C# .NET 建立 ASP.NET 應用程式

  1. 開啟 Visual Studio .NET。
  2. 建立新的 ASP.NET Web 應用程式,並指定其名稱和位置。
back to the top

在 Web.config 檔案中設定安全性設定

本節示範如何新增和修改 <驗證><授權> 設定區段以便將 ASP.NET 應用程式設定為使用表單型驗證。
  1. 在 [方案總管] 中開啟 Web.config 檔案。
  2. 將驗證模式變更成 [表單]
  3. 插入 <Forms> 標籤,並填入適當屬性。(如需有關這些屬性的詳細資訊,請參閱<參考>一節中所列的 MSDN 文件或「快速入門」文件)。複製下列程式碼,然後按一下 [編輯] 功能表上的 [貼成 HTML] 將程式碼貼到檔案的 <驗證> 區段:
    <authentication mode="Forms"><forms name=".ASPXFORMSDEMO" loginUrl="logon.aspx" protection="All" path="/" timeout="30" /></authentication> 					
  4. <驗證> 區段中貼上下列程式碼,以拒絕匿名使用者的存取:
    <authorization><deny users ="?" /><allow users = "*" /></authorization>					
back to the top

建立範例資料庫資料表來儲存使用者詳細資料

本節示範如何建立範例資料庫來儲存使用者名稱、密碼和使用者的角色。如果您要在資料庫中儲存使用者角色和實作角色安全性,就需要用到角色欄位。
  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]GOCREATE TABLE [dbo].[Users] ([uname] [varchar] (15) NOT NULL ,[Pwd] [varchar] (25) NOT NULL ,[userRole] [varchar] (25) NOT NULL ,) ON [PRIMARY]GOALTER TABLE [dbo].[Users] WITH NOCHECK ADD CONSTRAINT [PK_Users] PRIMARY KEY  NONCLUSTERED    ([uname])  ON [PRIMARY] GOINSERT 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 電腦的 Query Analyzer 開啟 Users.sql。再從資料庫清單中,按一下 pubs,執行這段指令碼。這樣便會在本範例應用程式會用到的 Pubs 資料庫中,建立並填入範例使用者資料表。
back to the top

建立 Logon.aspx 頁面

  1. 在名為 Logon.aspx 的專案中加入新的網頁表單。
  2. 在編輯器中開啟 Logon.aspx 頁面,並切換成 HTML 檢視。
  3. 複製下列程式碼,並使用 [編輯] 功能表上的 [貼成 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" />						
    Web 表單是給使用者填寫的登入表單,以便他們提供使用者名稱和密碼來登入應用程式。
  4. 切換至 [設計] 檢視,再儲存此頁面。
back to the top

將事件處理常式編寫成程式碼以便驗證使用者認證

本節列出放置於程式碼後置頁面 (Logon.aspx.cs) 中的程式碼。
  1. 按兩下 [登入] 以開啟 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;	// 檢查是否有無效的 userName。	// userName 不得為 Null 且長度必須介於 1 到 15 個字元。	if ( (  null == userName ) || ( 0 == userName.Length ) || ( userName.Length > 15 ) )	{		System.Diagnostics.Trace.WriteLine( "[ValidateUser] Input validation of userName failed." );		return false;	}	// 檢查是否有無效的密碼。	// 密碼不得為 Null 且長度必須介於 1 到 25 個字元。	if ( (  null == passWord ) || ( 0 == passWord.Length ) || ( passWord.Length > 25 ) )	{		System.Diagnostics.Trace.WriteLine( "[ValidateUser] 密碼的輸入驗證失敗。" );		return false;	}	try	{		// 請洽詢 SQL Server 系統管理員取得		// 用來連線本機 SQL Server 的適當連線字串。		conn = new SqlConnection( "server=localhost;Integrated Security=SSPI;database=pubs" );		conn.Open();		// 建立 SqlCommand 以便從提供的 userName 表格選取密碼欄位。		cmd = new SqlCommand( "Select pwd from users where uname=@userName", conn );		cmd.Parameters.Add( "@userName", SqlDbType.VarChar, 25 );		cmd.Parameters["@userName"].Value = userName;		// 執行命令並將密碼欄位擷取到 lookupPassword 字串。		lookupPassword = (string) cmd.ExecuteScalar();		// 清理命令和連線物件。		cmd.Dispose();		conn.Dispose();	}	catch ( Exception ex )	{		// 在這裡新增錯誤處理方式以便進行偵錯。		// 不應將此錯誤訊息傳回給呼叫者。		System.Diagnostics.Trace.WriteLine( "[ValidateUser] Exception " + ex.Message );	}	// 如果找不到密碼,請傳回 false。	if ( null == lookupPassword ) 	{		// 您可以將這裡的失敗登入嘗試寫入事件記錄檔以增強安全性。		return false;	}	//使用可區分大小寫的比較方式,將 lookupPassword 和輸入密碼進行比較。	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);   }elseResponse.Redirect("logon.aspx", true);}						
  5. 請確認下列程式碼已新增到 Web 表單設計工具產生的程式碼中的 InitializeComponent 方法。
    this.cmdLogin.ServerClick += new System.EventHandler(this.cmdLogin_ServerClick);					
back to the top

建立 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. 儲存並編譯專案。您現在可以使用這個應用程式。
back to the top

其他注意事項

  • 您可能會希望能在資料庫中安全地儲存密碼。您可以使用名為 HashPasswordForStoringInConfigFileFormsAuthentication 類別公用程式函式先為密碼進行加密,再將密碼儲存到資料庫或設定檔中。
  • 您可以將 SQL 連線資訊儲存到設定檔 (Web.config),以在必要時方便進行修改。
  • 您可以考慮加入程式碼來防止駭客使用不同密碼組合登入。例如,您可以包含只接受二次或三次嘗試登入次數的邏輯。如果使用者無法在特定嘗試次數之內完成登入,您可以在資料庫中設定旗標,設定在該使用者造訪不同頁面或撥打支援電話來重新啟用其帳戶之前,皆不允許該使用者登入。此外,您應該在任何必要時機加入適當的錯誤處理。
  • 由於會根據驗證 Cookie 來加以識別使用者,所以您可能想這個應用程式中使用 Secure Sockets Layer (SSL),防止任何人欺騙驗證 Cookie 和傳送過程中的任何有價資訊。
  • 表單型驗證會要求用戶端接受或是啟用瀏覽器的 Cookie 功能。
  • <authentication> 設定區段的 timeout 參數會控制驗證 Cookie 的產生時間間隔。您可以選擇可提供較高效能和安全性的值。
  • 某些在 Internet 上的中繼 Proxy 和快取,會快取其中包含 Set-Cookie 標題的 Web 伺服器回應,並將這些標題傳回給不同使用者。由於表單型驗證會使用 Cookie 來驗證使用者,因此如果在此時接收到從非原來指定使用的中繼 Proxy 或快取發出的 Cookie,就可能會讓使用者不小心 (或故意) 模擬其他使用者。
back to the top
参考
如需有關如何使用 <credentials> 區段來儲存使用者資料和密碼,以便實作簡易表單型驗證的詳細資訊,請參閱下列 GotDotNet ASP.NET 快速入門範例: 如需有關如何實作使用 XML 檔案儲存使用者和密碼的表單型驗證的詳細資訊,請參閱下列 .NET Framework 軟體開發套件 (SDK) 文件中的主題:
使用 XML 使用者檔案的表單型驗證
http://msdn.microsoft.com/zh-tw/library/1b1y85bh(vs.71).aspx
如需有關 ASP.NET Web 應用程式安全性的詳細資訊,請參閱下列 Microsoft .NET Framework 開發人員指南文件: 如需有關 System.Web.Security 命名空間的詳細資訊,請參閱下列 Microsoft .NET Framework 參考文件: 如需有關 ASP.NET 設定的詳細資訊,請參閱下列 Microsoft .NET Framework 開發人員指南文章: 如需有關 ASP.NET 安全性方針的詳細資訊,請參閱下列 MSDN 白皮書:
ASP.NET:.NET 安全性指導中的驗證
http://msdn.microsoft.com/zh-tw/library/ms978378.aspx
如需有關 ASP.NET 的更多一般資訊,請參閱下列 MSDN 新聞群組:back to the top
注意 :本文屬於「快速發佈」文章,係由 Microsoft 技術支援或組織內部直接建立。 本文所包含的資訊是為了回應新問題而依現況提供。 因此為了迅速對外發佈,文章內容可能含有印刷錯誤,而且可能會在不另行通知的情況下進行修改。 如需其他考量事項,請參閱使用規定
內容

文章識別碼:301240 - 最後檢閱時間:07/03/2012 08:43:00 - 修訂: 1.0

Microsoft ASP.NET 1.1, Microsoft Visual C# .NET 2003 標準版, Microsoft ASP.NET 1.0, Microsoft Visual C# .NET 2002 Standard Edition, Microsoft SQL Server 2000 Standard Edition, Microsoft SQL Server 7.0 Standard Edition, Microsoft SQL Server 2000 64-bit Edition

  • kbconfig kbhowtomaster kbsecurity kbweb KB301240
意見反應