共用方式為


在 SQL Server 中建立成員資格結構描述 (C#)

作者 :Scott Mitchell

注意

自本文撰寫以來,ASP.NET 成員資格提供者已被 ASP.NET 身分識別取代。 強烈建議您更新應用程式以使用 ASP.NET 身分識別 平臺,而不是本文撰寫時精選的成員資格提供者。 ASP.NET 身分識別對於 ASP.NET 成員資格系統有一些優點,包括 :

  • 更好的效能
  • 改善擴充性和可測試性
  • 支援 OAuth、OpenID Connect 和雙因素驗證
  • 宣告型身分識別支援
  • 與 ASP.Net Core 更好的互操作性

下載程式代碼下載 PDF

本教學課程一開始會檢查將必要架構新增至資料庫的技術,以使用 SqlMembershipProvider。 接下來,我們將檢查架構中的索引鍵數據表,並討論其用途和重要性。 本教學課程將說明如何告訴 ASP.NET 應用程式應使用成員資格架構的提供者。

簡介

前兩個教學課程會使用窗體驗證來識別網站訪客。 窗體驗證架構可讓開發人員輕鬆地將使用者登入網站,並透過使用驗證票證在頁面流覽時記住這些窗體驗證架構。 類別 FormsAuthentication 包含產生票證的方法,並將它新增至訪客的Cookie。 會 FormsAuthenticationModule 檢查所有傳入要求,並針對具有有效驗證票證的要求,建立和關聯 GenericPrincipal 和物件與 FormsIdentity 目前的要求。 窗體驗證只是在登入時將驗證票證授與訪客的機制,並在後續要求上剖析該票證以判斷使用者的身分識別。 若要讓 Web 應用程式支援使用者帳戶,我們仍然需要實作使用者存放區,並新增功能來驗證認證、註冊新使用者,以及大量其他使用者帳戶相關工作。

在 ASP.NET 2.0 之前,開發人員已掛接實作所有這些使用者帳戶相關工作。 幸運的是,ASP.NET 小組已辨識此缺點,並引進了 ASP.NET 2.0 的成員資格架構。 成員資格架構是 .NET Framework 中的一組類別,可提供程式設計介面來完成核心使用者帳戶相關工作。 此架構建置在 提供者模型之上,可讓開發人員將自定義實作插入標準化 API。

安全性基本概念和 ASP.NET 支援教學課程中所述,.NET Framework 隨附兩個內建成員資格提供者:ActiveDirectoryMembershipProviderSqlMembershipProvider。 如其名稱所示,會SqlMembershipProvider使用 Microsoft SQL Server 資料庫作為使用者存放區。 為了在應用程式中使用此提供者,我們必須告訴提供者要使用哪個資料庫做為存放區。 如您所想像,使用者 SqlMembershipProvider 存放資料庫預期會有特定的資料庫數據表、檢視表和預存程式。 我們需要將此預期的架構新增至選取的資料庫。

本教學課程一開始會檢查將必要架構新增至資料庫的技術,以便使用 SqlMembershipProvider。 接下來,我們將檢查架構中的索引鍵數據表,並討論其用途和重要性。 本教學課程將說明如何告訴 ASP.NET 應用程式應使用成員資格架構的提供者。

現在就開始吧!

步驟 1:決定使用者存放區的位置

ASP.NET 應用程式的數據通常會儲存在資料庫中的數個數據表中。 實作 SqlMembershipProvider 資料庫架構時,我們必須決定是否要將成員資格架構放在與應用程式數據相同的資料庫中,還是放在替代資料庫中。

基於下列原因,建議您在與應用程式數據相同的資料庫中尋找成員資格架構:

  • 可維護性 ' 資料封裝在一個資料庫中的應用程式比具有兩個不同資料庫的應用程式更容易瞭解、維護和部署。
  • 關係型完整性 ' 藉由在與應用程式數據表相同的資料庫中尋找成員資格相關數據表,就可以在成員資格相關數據表和相關應用程式數據表的主 鍵之間建立外鍵條件約束

如果您有多個應用程式使用個別的資料庫,但需要共用一般使用者存放區,則使用者存放區和應用程式數據分離成不同的資料庫才有意義。

建立資料庫

我們建置的應用程式,因為第二個教學課程尚未需要資料庫。 不過,我們需要一個使用者存放區。 讓我們建立一個 ,然後新增至提供者所需的 SqlMembershipProvider 架構 (請參閱步驟 2) 。

注意

在本教學課程系列中,我們將使用 Microsoft SQL Server 2005 Express Edition 資料庫來儲存應用程式數據表和SqlMembershipProvider架構。 此決策基於兩個原因而做出:首先,由於成本 - 免費 - Express Edition 是 2005 SQL Server 最易讀的版本;第二,SQL Server 2005 Express Edition 資料庫可以直接放在 Web 應用程式的App_Data資料夾,讓它成為將資料庫和 Web 應用程式封裝在一個 ZIP 檔案中,並重新部署,而不需任何特殊的安裝指示或組態選項。 如果您想要遵循非 Express Edition 版本的 SQL Server,請放心。 這些步驟幾乎完全相同。 此SqlMembershipProvider架構會與任何版本的 Microsoft SQL Server 2000 和版本搭配運作。

從 方案總管,以滑鼠右鍵按單擊App_Data資料夾,然後選擇 [新增專案]。 (如果您沒有在專案中看到App_Data資料夾,請以滑鼠右鍵按兩下 方案總管 中的項目,選取 [新增 ASP.NET 資料夾],然後從 [新增專案] 對話框中挑選 App_Data.) ,選擇新增名為 SecurityTutorials.mdf的新 SQL Database。 在本教學課程中,我們會將架構新增 SqlMembershipProvider 至此資料庫;在後續的教學課程中,我們將建立其他數據表來擷取應用程序數據。

將名為 SecurityTutorials.mdf 資料庫的新 SQL Database 新增至 App_Data資料夾

圖 1:將新的 SQL Database 具名SecurityTutorials.mdf資料庫新增至App_Data資料夾, (按兩下即可檢視完整大小的影像)

將資料庫 App_Data 加入資料夾會自動包含在 [資料庫總管] 檢視中。 (在非 Express Edition 版本的 Visual Studio 中,資料庫總管稱為 [伺服器總管]。) 移至 [資料庫總管],然後展開剛加入 SecurityTutorials 的資料庫。 如果您在畫面上看不到 [資料庫總管],請移至 [檢視] 功能表並選擇 [資料庫總管],或按 Ctrl+Alt+S。 如圖 2 所示,資料庫是空的 SecurityTutorials , 資料庫不包含數據表、檢視表和預存程式。

SecurityTutorials 資料庫目前是空的

圖 2:資料庫 SecurityTutorials 目前是空的 (按兩下即可檢視完整大小的映像)

步驟 2:將SqlMembershipProvider架構新增至資料庫

SqlMembershipProvider需要將一組特定的數據表、檢視表和預存程式安裝在使用者存放區資料庫中。 您可以使用 工具來新增aspnet_regsql.exe這些必要資料庫物件。 此檔案位於 %WINDIR%\Microsoft.Net\Framework\v2.0.50727\ 資料夾中。

注意

此工具 aspnet_regsql.exe 同時提供命令行功能和圖形用戶介面。 圖形化介面更方便使用,也是我們將在本教學課程中檢查的內容。 當新增 SqlMembershipProvider 架構需要自動化時,命令行介面很有用,例如在建置腳本或自動化測試案例中。

此工具aspnet_regsql.exe可用來將 ASP.NET 應用程式服務新增或移除至指定的 SQL Server 資料庫。 ASP.NET 應用程式服務包含和SqlRoleProvider的架構SqlMembershipProvider,以及其他 ASP.NET 2.0 架構之 SQL 架構提供者的架構。 我們需要為工具提供兩個資訊 aspnet_regsql.exe

  • 是否要新增或移除應用程式服務,以及
  • 要加入或移除應用程式服務架構的資料庫

在提示資料庫使用時 aspnet_regsql.exe ,此工具會要求我們提供資料庫所在的伺服器名稱、連線到資料庫的安全性認證,以及資料庫名稱。 如果您使用非 Express 版本的 SQL Server,您應該已經知道這項資訊,因為它與透過 ASP.NET 網頁使用資料庫時必須透過 連接字串 提供的資訊相同。 不過,在資料夾中使用 SQL Server 2005 Express Edition 資料庫App_Data時,判斷伺服器和資料庫名稱會更加相關。

下一節會檢查在資料夾中指定 SQL Server 2005 Express Edition 資料庫的App_Data伺服器和資料庫名稱的簡單方式。 如果您未使用 SQL Server 2005 Express Edition 請直接跳到安裝應用程式服務一節。

在資料夾中判斷 SQL Server 2005 Express Edition 資料庫的伺服器和資料庫App_Data名稱

為了使用此工具, aspnet_regsql.exe 我們需要知道伺服器和資料庫名稱。 伺服器名稱稱為 localhost\InstanceName。 最有可能的是 ,InstanceNameSQLExpress。 不過,如果您手動安裝 SQL Server 2005 Express Edition (,則安裝Visual Studio) 時,您並未自動安裝它,則您可能會選取不同的實例名稱。

資料庫名稱是一個比較棘手的判斷。 App_Data資料夾中的資料庫通常會有資料庫名稱,其中包含全域唯一標識碼以及資料庫檔案的路徑。 我們需要判斷此資料庫名稱,才能透過 aspnet_regsql.exe新增應用程式服務架構。

確定資料庫名稱最簡單的方式是透過 SQL Server Management Studio 檢查資料庫名稱。 SQL Server Management Studio 提供用於管理 SQL Server 2005 資料庫的圖形化介面,但不會隨附於 express Edition of SQL Server 2005。 好消息是您可以下載免費的 Express Edition SQL Server Management Studio。

注意

如果您的桌面上也安裝了非 Express Edition 版本 SQL Server 2005,則可能會安裝完整的 Management Studio 版本。 您可以使用完整版本來判斷資料庫名稱,並遵循與下列 Express Edition 所述的相同步驟。

從關閉 Visual Studio 開始,以確保 Visual Studio 在資料庫檔案上加加的任何鎖定都已關閉。 接下來,啟動 SQL Server Management Studio 並連線到localhost\InstanceName資料庫以進行 SQL Server 2005 Express Edition。 如先前所述,實例名稱的機率是 SQLExpress。 針對 [驗證] 選項,選取 [Windows 驗證]。

線上到 SQL Server 2005 Express Edition 實例

圖 3:連線到 SQL Server 2005 Express Edition 實例, (按兩下即可檢視完整大小的映像)

聯機到 SQL Server 2005 Express Edition 實例之後,Management Studio 會顯示 [資料庫]、[安全性設定]、[伺服器物件] 等資料夾。 如果您展開 [資料庫] 索引標籤,您會看到 SecurityTutorials.mdf 資料庫 在資料庫實例中註冊 - 我們需要先附加資料庫。

以滑鼠右鍵按兩下 [資料庫] 資料夾,然後從操作選單中選擇 [附加]。 這會顯示 [附加資料庫] 對話框。 從這裡按兩下 [新增] 按鈕,流覽至 SecurityTutorials.mdf 資料庫,然後按兩下 [確定]。 圖 4 顯示選取資料庫之後的 SecurityTutorials.mdf [附加資料庫] 對話框。 圖 5 顯示成功附加資料庫之後,Management Studio 的 物件總管。

附加SecurityTutorials.mdf資料庫

圖 4:附加 SecurityTutorials.mdf 資料庫 (按下即可檢視完整大小的映射)

SecurityTutorials.mdf資料庫會出現在 Databases 資料夾中

圖 5SecurityTutorials.mdf 資料庫會出現在 [資料庫] 資料夾中, (按兩下即可檢視大小完整的影像)

如圖 5 所示, SecurityTutorials.mdf 資料庫具有相當中止的名稱。 讓我們將其變更為更容易記住的 (,並更容易輸入) 名稱。 以滑鼠右鍵按兩下資料庫,從操作功能表中選擇 [重新命名],然後將它重新命名。SecurityTutorialsDatabase 這不會變更檔名,只是資料庫用來識別本身的名稱來 SQL Server。

將資料庫重新命名為 SecurityTutorialsDatabase

圖 6:將資料庫重新命名為 SecurityTutorialsDatabase (按兩下即可檢視完整大小的映像)

此時,我們知道資料庫檔案的伺服器 SecurityTutorials.mdf 和資料庫名稱: localhost\InstanceNameSecurityTutorialsDatabase。 我們現在已準備好透過 aspnet_regsql.exe 工具安裝應用程式服務。

安裝應用程式服務

若要啟動 aspnet_regsql.exe 此工具,請移至 [開始] 功能表,然後選擇 [執行]。 在文字框中輸入 %WINDIR%\Microsoft.Net\Framework\v2.0.50727\aspnet_regsql.exe ,然後按下 [確定]。 或者,您可以使用 Windows 檔案總管向下切入至適當的資料夾,然後按兩下檔案 aspnet_regsql.exe 。 任一種方法都會達到相同的結果。

aspnet_regsql.exe在沒有任何命令行自變數的情況下執行此工具,會啟動 [ASP.NET SQL Server安裝精靈] 圖形用戶介面。 精靈可讓您輕鬆地在指定的資料庫上新增或移除 ASP.NET 應用程式服務。 精靈的第一個畫面,如圖 7 所示,描述工具的目的。

使用 ASP.NET SQL Server安裝精靈進行新增成員資格架構

圖 7:使用 [ASP.NET SQL Server安裝精靈建立] 來新增成員資格架構 (按兩下即可檢視完整大小的映像)

精靈中的第二個步驟會詢問我們是否要新增應用程式服務或將其移除。 由於我們想要新增 所需的SqlMembershipProvider資料表、檢視表和預存程式,請選擇 [為應用程式服務設定 SQL Server] 選項。 稍後,如果您想要從資料庫移除此架構,請重新執行此精靈,但改為選擇 [從現有的資料庫移除應用程式服務資訊] 選項。

選擇 [為應用程式服務設定 SQL Server 選項

圖 8:選擇 [為應用程式服務設定 SQL Server 選項 (按兩下以檢視完整大小的映像)

第三個步驟會提示資料庫資訊:伺服器名稱、驗證資訊和資料庫名稱。 如果您已遵循本教學課程,並將資料庫新增 SecurityTutorials.mdfApp_Data,並將其附加至 localhost\InstanceName,並將它重新命名為 SecurityTutorialsDatabase,請使用下列值:

  • 伺服器:localhost\InstanceName
  • Windows 驗證
  • 資料庫:SecurityTutorialsDatabase

輸入資料庫資訊

圖 9:輸入資料庫資訊 (按一下以檢視完整大小的映像)

輸入資料庫信息之後,按 [下一步]。 最後一個步驟摘要說明將採取的步驟。 按 [下一步] 安裝應用程式服務,然後按兩下 [完成] 以完成精靈。

注意

如果您使用 Management Studio 附加資料庫並重新命名資料庫檔案,請務必先卸離資料庫並關閉 Management Studio,再重新開啟 Visual Studio。 若要卸離 SecurityTutorialsDatabase 資料庫,請以滑鼠右鍵按單擊資料庫名稱,然後從 [工作] 功能表中,選擇 [中斷連結]。

精靈完成時,返回 Visual Studio 並流覽至 [資料庫總管]。 展開 [資料表] 資料夾。 您應該看到一系列資料表,名稱開頭為 前置詞 aspnet_。 同樣地,您可以在 [檢視] 和 [預存程式] 資料夾下找到各種檢視和預存程式。 這些資料庫物件組成應用程式服務架構。 我們將檢查步驟 3 中的成員資格和角色特定資料庫物件。

已將各種數據表、檢視表和預存程式新增至資料庫

圖 10:已將各種數據表、檢視和預存程式新增至資料庫 (按兩下即可檢視完整大小的影像)

注意

工具 aspnet_regsql.exe 的圖形使用者介面會安裝整個應用程式服務架構。 但是從命令行執行 aspnet_regsql.exe 時,您可以指定要安裝 (或移除) 的特定應用程式服務元件。 因此,如果您想要只新增 和 提供者所需的SqlMembershipProvider數據表、檢視表和預存程式,請從命令行執行aspnet_regsql.exeSqlRoleProvider 或者,您也可以手動執行 所使用的適當 T-SQL 建立腳本 aspnet_regsql.exe子集。 這些文稿位於WINDIR%\Microsoft.Net\Framework\v2.0.50727\名稱如下的資料夾中,例如 InstallCommon.sqlInstallMembership.sqlInstallRoles.sqlInstallProfile.sqlInstallSqlState.sql、 等等。

此時,我們已建立 所需的 SqlMembershipProvider資料庫物件。 不過,我們仍然需要指示成員資格架構應該使用 SqlMembershipProvider (ActiveDirectoryMembershipProvider 與) ,以及 SqlMembershipProvider 應該使用 SecurityTutorials 資料庫。 我們將探討如何指定要使用的提供者,以及如何在步驟 4 中自定義所選提供者的設定。 但首先,讓我們深入瞭解剛建立的資料庫物件。

步驟 3:查看架構的核心數據表

在 ASP.NET 應用程式中使用成員資格和角色架構時,實作詳細數據會由提供者封裝。 在未來的教學課程中,我們將透過 .NET Framework的 MembershipRoles 類別來與這些架構互動。 使用這些高階 API 時,我們不需要擔心低階的詳細數據,例如執行哪些查詢,或和SqlRoleProvider修改SqlMembershipProvider了哪些數據表。

因此,我們可以放心地使用成員資格和角色架構,而不需要探索步驟 2 中建立的資料庫架構。 不過,建立數據表來儲存應用程式數據時,可能需要建立與使用者或角色相關的實體。 在應用程式數據表與步驟 2 中建立的數據表之間建立外鍵條件約束時,有助於熟悉 SqlMembershipProviderSqlRoleProvider 架構。 此外,在某些罕見的情況下,我們可能需要直接與使用者和角色儲存在資料庫層級 (,而不是透過 MembershipRoles 類別) 。

將使用者存放區分割成應用程式

成員資格和角色架構的設計,讓單一使用者和角色存放區可以在許多不同的應用程式之間共用。 使用成員資格或角色架構 ASP.NET 應用程式必須指定要使用的應用程式分割區。 簡單地說,多個 Web 應用程式可以使用相同的使用者和角色存放區。 圖 11 描述分割成三個應用程式的使用者和角色存放區:HRSite、CustomerSite 和 SalesSite。 這三個 Web 應用程式各自有自己的唯一使用者和角色,但它們全都會在相同的資料庫數據表中實際儲存其用戶帳戶和角色資訊。

用戶帳戶可跨多個應用程式分割

圖 11:使用者帳戶可能會分割到多個應用程式 (按兩下即可檢視完整大小的映像)

數據表 aspnet_Applications 是定義這些分割區的內容。 使用此資料庫來儲存使用者帳戶資訊的每個應用程式都會以此數據表中的數據列來表示。 資料表 aspnet_Applications 有四個資料列: ApplicationIdApplicationNameLoweredApplicationNameDescriptionApplicationIduniqueidentifier 別為 ,而且是數據表的主鍵; ApplicationName 為每個應用程式提供唯一的易記名稱。

其他成員資格和角色相關數據表會連結回 ApplicationId 中的 aspnet_Applications欄位。 例如,包含每個用戶帳戶記錄的 aspnet_Users 數據表具有 ApplicationId 外鍵字段;數據表的 aspnet_Roles ditto。 ApplicationId這些數據表中的欄位會指定使用者帳戶或角色所屬的應用程式分割區。

儲存用戶帳戶資訊

使用者帳戶資訊位於兩個資料表中: aspnet_Usersaspnet_Membership。 數據表 aspnet_Users 包含保留基本用戶帳戶資訊的欄位。 三個最相關的數據行包括:

  • UserId
  • UserName
  • ApplicationId

UserId 是主鍵 (且類型 uniqueidentifier 為) 。 UserName 類型為 nvarchar(256) ,且密碼會組成用戶的認證。 (使用者的密碼會儲存在 aspnet_Membership table 中。) ApplicationId 會將使用者帳戶連結至 中的 aspnet_Applications特定應用程式。 和 ApplicationId 數據行上有UserName復合UNIQUE條件約束。 這可確保在指定的應用程式中,每個UserName都是唯一的,但允許 UserName 在不同的應用程式中使用相同的名稱。

數據表 aspnet_Membership 包含其他使用者帳戶資訊,例如使用者的密碼、電子郵件位址、上次登入日期和時間等等。 和 aspnet_Membership 數據表中的aspnet_Users記錄之間有一對一的對應。 這個關聯性是由 UserId 中的 aspnet_Membership欄位所確保,此欄位會做為數據表的主鍵。 aspnet_Users如同數據表,包含一個ApplicationId字段,aspnet_Membership會將這項資訊系結至特定應用程式分割區。

正在保護密碼

密碼資訊會儲存在數據表中 aspnet_MembershipSqlMembershipProvider允許使用下列三種技術之一,將密碼儲存在資料庫中:

  • 清除 - 密碼會以純文字形式儲存在資料庫中。 我強烈建議不要使用此選項。 如果資料庫遭到入侵 - 由駭客尋找後門或具有數據庫存取權的不合員工所造成 - 每位使用者的認證都可供取用。
  • 哈希 - 使用單向哈希演算法和隨機產生的 Salt 值來哈希密碼。 這個哈希值 (以及 salt) 儲存在資料庫中。
  • 加密 - 密碼的加密版本會儲存在資料庫中。

所使用的密碼儲存技術取決於 SqlMembershipProvider 中指定的 Web.config設定。 我們將探討如何自定義 SqlMembershipProvider 步驟 4 中的設定。 默認行為是儲存密碼的哈希。

負責儲存密碼的資料行為 PasswordPasswordFormatPasswordSaltPasswordFormat 是類型的 int 欄位,其值表示用來儲存密碼的技術:0 代表 Clear;1 代表哈希;2 代表 Encrypted。 PasswordSalt 不論使用的密碼儲存技術為何,都會指派隨機產生的字串;的值 PasswordSalt 只有在計算密碼的哈希時才會使用。 最後,數據 Password 行包含實際的密碼數據,可能是純文本密碼、密碼哈希或加密密碼。

表 1 說明這三個數據行在儲存密碼 MySecret 時,這些三個數據行看起來可能的樣子! .

儲存技術<_o3a_p /> 密碼<_o3a_p /> PasswordFormat<_o3a_p /> PasswordSalt<_o3a_p />
清除 MySecret! 0 tTnkPlesqissc2y2SMEygA==
雜湊 2oXm6sZHWbTHFgjgkGQsc2Ec9ZM= 1 wFgjUfhdUFOCKQiI61vtiQ==
已加密 62RZgDvhxykkqsMchZ0Yly7HS6onhpaoCYaRxV8g0F4CW56OXU3e7Inza9j9BKp 2 LSRzhGS/aa/oqAXGLHJNBw==

表 1:儲存密碼 MySecret 時,Password-Related 字段的範例值!

注意

所使用的 SqlMembershipProvider 特定加密或哈希演算法是由 元素中的 <machineKey> 設定所決定。

儲存角色和角色關聯

角色架構可讓開發人員定義一組角色,並指定哪些用戶屬於哪些角色。 此資訊是透過兩個資料表在資料庫中擷取: aspnet_Rolesaspnet_UsersInRoles。 數據表中的每個 aspnet_Roles 記錄都代表特定應用程式的角色。 與數據表類似 aspnet_Usersaspnet_Roles 數據表有三個與討論相關的數據行:

  • RoleId
  • RoleName
  • ApplicationId

RoleId 是主鍵 (,且類型 uniqueidentifier 為) 。 RoleNamenvarchar(256) 類型。 並將 ApplicationId 用戶帳戶連結至 中的 aspnet_Applications特定應用程式。 和 ApplicationId 資料行上有RoleName復合UNIQUE條件約束,可確保在指定的應用程式中,每個角色名稱都是唯一的。

數據表 aspnet_UsersInRoles 可作為使用者與角色之間的對應。 只有兩個數據行 - UserIdRoleId - 並組成複合主鍵。

步驟 4:指定提供者並自定義其設定

所有支援提供者模型的架構,例如成員資格和角色架構,都缺乏實作詳細數據,而是將該責任委派給提供者類別。 在成員資格架構的情況下,類別 Membership 會定義用來管理用戶帳戶的API,但不會直接與任何使用者存放區互動。 相反地,類別 Membership 的 方法會將要求交給已設定的提供者 -我們將使用 SqlMembershipProvider。 當我們在 類別中 Membership 叫用其中一個方法時,成員資格架構如何知道將呼叫委派給 SqlMembershipProvider

類別 Membership 具有 Providers 屬性 ,其中包含成員資格架構可用之所有已註冊提供者類別的參考。 每個已註冊的提供者都有相關聯的名稱和類型。 此名稱提供人類易記的方式來參考集合中的 Providers 特定提供者,而類型則會識別提供者類別。 此外,每個已註冊的提供者可能包含組態設定。 成員資格架構的組態設定包括 passwordFormatrequiresUniqueEmail,以及其他許多設定。 如需 所使用的 SqlMembershipProvider組態設定完整清單,請參閱表 2。

屬性 Providers 的內容是透過 Web 應用程式的組態設定來指定。 根據預設,所有 Web 應用程式都有名為 AspNetSqlMembershipProviderSqlMembershipProvider提供者。 這個預設成員資格提供者會在 位於 的 (%WINDIR%\Microsoft.Net\Framework\v2.0.50727\CONFIG)machine.config註冊:

<membership>
 <providers>
 <add name="AspNetSqlMembershipProvider"
 type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 
 connectionStringName="LocalSqlServer"
 enablePasswordRetrieval="false"
 enablePasswordReset="true"
 requiresQuestionAndAnswer="true"
 applicationName="/"
 requiresUniqueEmail="false"
 passwordFormat="Hashed"
 maxInvalidPasswordAttempts="5"
 minRequiredPasswordLength="7"
 minRequiredNonalphanumericCharacters="1"
 passwordAttemptWindow="10"
 passwordStrengthRegularExpression=""/>
 </providers> 
</membership>

如上述標記所示,專案<membership>會定義成員資格架構的組態設定,而<providers>子元素則指定已註冊的提供者。 提供者可以使用 或 <remove> 元素來新增或移除<add>;使用 <clear> 元素來移除所有目前已註冊的提供者。 如上述標記所示, machine.config 新增名為 AspNetSqlMembershipProvider 類型的 SqlMembershipProvider提供者。

除了 nametype 屬性之外, <add> 元素還包含屬性,這些屬性會定義各種設定設定的值。 表 2 列出可用的 SqlMembershipProvider特定組態設定,以及每個設定的描述。

注意

表 2 中提及的任何預設值都會參考 類別中 SqlMembershipProvider 定義的預設值。 請注意,中並非所有組態設定 AspNetSqlMembershipProvider 都對應至 類別的 SqlMembershipProvider 預設值。 例如,如果未在成員資格提供者中指定,則 requiresUniqueEmail 設定預設為 true。 不過,會 AspNetSqlMembershipProvider 藉由明確指定的值 false來覆寫這個預設值。

設定<_o3a_p /> 描述<_o3a_p />
ApplicationName 回想一下,成員資格架構可讓單一使用者存放區跨多個應用程式分割。 這個設定表示成員資格提供者所使用的應用程式分割區名稱。 如果未明確指定此值,則會在運行時間將它設定為應用程式虛擬根路徑的值。
commandTimeout 指定) 秒內 (的 SQL 命令逾時值。 預設值是 30。
connectionStringName 要用來連線到使用者存放區資料庫的 元素中 <connectionStrings> 連接字串 名稱。 這是必要的值。
description 提供已註冊提供者的易記描述。
enablePasswordRetrieval 指定使用者是否可以擷取忘記的密碼。 預設值是 false
enablePasswordReset 指出是否允許使用者重設其密碼。 預設值為 true
maxInvalidPasswordAttempts 在用戶鎖定之前,指定用戶期間 passwordAttemptWindow 可能會發生失敗的登入嘗試次數上限。預設值為 5。
minRequiredNonalphanumericCharacters 必須出現在用戶密碼中的非英數位元數目下限。 此值必須介於 0 到 128 之間;預設值為 1。
minRequiredPasswordLength 密碼中所需的字元數下限。 此值必須介於 0 到 128 之間;預設值為 7。
name 已註冊提供者的名稱。 這是必要的值。
passwordAttemptWindow 追蹤失敗登入嘗試的分鐘數。 如果使用者在此指定的視窗中提供無效的登入認證 maxInvalidPasswordAttempts 時間,則會遭到鎖定。預設值為 10。
PasswordFormat 密碼儲存格式: ClearHashedEncrypted。 預設值為 Hashed
passwordStrengthRegularExpression 如果提供,則會使用此正則表達式來評估建立新帳戶時或變更其密碼時,使用者所選密碼的強度。 預設值為空字串。
requiresQuestionAndAnswer 指定使用者在擷取或重設密碼時,是否必須回答其安全性問題。 預設值是 true
requiresUniqueEmail 指出指定應用程式分割區中的所有用戶帳戶是否都必須有唯一的電子郵件位址。 預設值是 true
type 指定提供者的類型。 這是必要的值。

表 2:成員資格和 SqlMembershipProvider 組態設定

除了 AspNetSqlMembershipProvider之外,其他成員資格提供者也可以藉由將類似的標記新增至 Web.config 檔案,以應用程式為基礎註冊。

注意

角色架構的運作方式大致相同:在 中 machine.config 有默認註冊的角色提供者,而註冊的提供者可能會在 中依應用程式自定義 Web.config。 我們將在未來的教學課程中詳細檢查角色架構及其組態標記。

自訂設定SqlMembershipProvider

預設 SqlMembershipProvider () AspNetSqlMembershipProviderconnectionStringName 屬性設定為 LocalSqlServerAspNetSqlMembershipProvider如同提供者,連接字串 名稱LocalSqlServer定義於 中machine.config

<connectionStrings> 
 <add name="LocalSqlServer" 
 connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" 
 providerName="System.Data.SqlClient"/> 
</connectionStrings>

如您所見,此 連接字串 定義位於 的 SQL 2005 Express Edition 資料庫 |DataDirectory|aspnetdb.mdf'。 字串 |DataDirectory|會在運行時間轉譯為指向 ~/App_Data/ 目錄,因此資料庫路徑 |DataDirectory|aspnetdb.mdf“ 會轉譯為 ~/App_Data/aspnet.mdf

如果我們未在應用程式的Web.config檔案中指定任何成員資格提供者資訊,則應用程式會使用預設註冊的成員資格提供者 。 AspNetSqlMembershipProvider ~/App_Data/aspnet.mdf如果資料庫不存在,ASP.NET 運行時間會自動建立它,並新增應用程式服務架構。 不過,我們不想使用 aspnet.mdf 資料庫,而是想要使用 SecurityTutorials.mdf 我們在步驟 2 中建立的資料庫。 此修改可以透過下列兩種方式之一來完成:

  • 指定的值LocalSqlServer連接字串 中Web.config的名稱藉由覆LocalSqlServer寫 中的 Web.config連接字串 名稱值,我們可以使用預設的已註冊成員資格提供者 (AspNetSqlMembershipProvider) ,並讓它正確地使用SecurityTutorials.mdf資料庫。 如果您使用 所 AspNetSqlMembershipProvider指定的組態設定內容,這個方法就沒問題。 如需這項技術的詳細資訊,請參閱 Scott Guthrie 的部落格文章:Configure ASP.NET 2.0 Application Services to Use SQL Server 2000 或 SQL Server 2005
  • 新增類型的SqlMembershipProvider已註冊提供者並設定其connectionStringName設定為指向SecurityTutorials.mdf資料庫。除了資料庫 連接字串 之外,此方法在您想要自定義其他組態屬性的案例中很有用。 在自己的專案中,我一律會使用此方法,因為其彈性和可讀性。

在我們可以新增參考SecurityTutorials.mdf資料庫的新已註冊提供者之前,我們必須先在 中的 <connectionStrings>Web.config區段中新增適當的 連接字串 值。 下列標記會新增名為 SecurityTutorialsConnectionString 的新 連接字串,以參考資料夾中 SQL Server 2005 Express Edition SecurityTutorials.mdf 資料庫App_Data

<configuration>
 <connectionStrings>
 <add name="SecurityTutorialsConnectionString" 
 connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\SecurityTutorials.mdf;Integrated Security=True;User Instance=True" 
 providerName="System.Data.SqlClient"/> 
 </connectionStrings> 
 <system.web>
 ... Configuration markup  removed for brevity ... 
 </system.web>
</configuration>

注意

如果您使用替代資料庫檔案,請視需要更新 連接字串。 如需有關形成正確 連接字串 的詳細資訊,請參閱 ConnectionStrings.com

接下來,將下列成員資格組態標記新增至 Web.config 檔案。 此標記會註冊名為 SecurityTutorialsSqlMembershipProvider的新提供者。

<configuration> 
 <connectionStrings>
 <add name="SecurityTutorialsConnectionString" 
 connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\SecurityTutorials.mdf;Integrated Security=True;User Instance=True" 
 providerName="System.Data.SqlClient"/>
 </connectionStrings> 
 <system.web>
 <membership defaultProvider="SecurityTutorialsSqlMembershipProvider">
 <providers>
 <!--Add a customized SqlMembershipProvider --> 
 <add name="SecurityTutorialsSqlMembershipProvider" 
 type="System.Web.Security.SqlMembershipProvider"
 connectionStringName="SecurityTutorialsConnectionString"
 enablePasswordRetrieval="false"
 enablePasswordReset="true"
 requiresQuestionAndAnswer="true"
 applicationName="SecurityTutorials"
 requiresUniqueEmail="true"
 passwordFormat="Hashed"
 maxInvalidPasswordAttempts="5"
 minRequiredPasswordLength="7"
 minRequiredNonalphanumericCharacters="1"
 passwordAttemptWindow="10"
 passwordStrengthRegularExpression=""/>
 </providers>
 </membership>
 ... Configuration markup removed for brevity ... 
 </system.web>
</configuration>

除了註冊 SecurityTutorialsSqlMembershipProvider 提供者之外,上述標記還會 SecurityTutorialsSqlMembershipProvider 透過 defaultProvider 專案) 中的 <membership> 屬性,將定義為預設提供者 (。 回想一下,成員資格架構可以有多個已註冊的提供者。 由於 AspNetSqlMembershipProvider 註冊為 中的 machine.config第一個提供者,除非另有指示,否則它會作為預設提供者。

目前,應用程式有兩個已註冊的提供者: AspNetSqlMembershipProviderSecurityTutorialsSqlMembershipProvider。 不過,在註冊SecurityTutorialsSqlMembershipProvider提供者之前,我們可以先在元素之前<add>立即新增<clear />元素,以清除所有先前註冊的提供者。 這會從已註冊的提供者清單中清除 AspNetSqlMembershipProvider ,這表示 SecurityTutorialsSqlMembershipProvider 會是唯一已註冊的成員資格提供者。 如果我們使用這種方法,則不需要將標示 SecurityTutorialsSqlMembershipProvider 為預設提供者,因為它是唯一已註冊的成員資格提供者。 如需使用<clear />的詳細資訊,請參閱在新增提供者時使用<clear />

請注意, SecurityTutorialsSqlMembershipProvider設定 connectionStringName 會參考剛加入 SecurityTutorialsConnectionString 連接字串 名稱,而且其applicationName設定已設定為 SecurityTutorials 的值。 此外, requiresUniqueEmail 設定已設定為 true。 所有其他組態選項都與 中的 AspNetSqlMembershipProvider值相同。 如果您想要的話,您可以在這裡進行任何設定修改。 例如,您可以藉由要求兩個非英數位元而非一個字元,或將密碼長度增加為八個字元,而不是七個字元,來強化密碼強度。

注意

回想一下,成員資格架構可讓單一使用者存放區跨多個應用程式分割。 成員資格提供者的 applicationName 設定會指出提供者在使用使用者存放區時所使用的應用程式。 請務必明確設定組 applicationName 態設定的值,因為如果未 applicationName 明確設定 ,則會在運行時間將它指派給 Web 應用程式的虛擬根路徑。 只要應用程式的虛擬根路徑不會變更,但如果您將應用程式移至不同的路徑,設定 applicationName 也會變更。 發生這種情況時,成員資格提供者會開始使用與先前使用不同的應用程式分割區。 在移動之前建立的使用者帳戶會位於不同的應用程式分割區中,而且那些使用者將無法再登入網站。 如需有關此問題的更深入討論,請參閱 設定 ASP.NET 2.0 成員資格和其他提供者時一律設定 applicationName 屬性

摘要

此時,我們有一個資料庫,其中包含已設定的應用程式服務 () SecurityTutorials.mdf ,並已設定 Web 應用程式,讓成員資格架構使用 SecurityTutorialsSqlMembershipProvider 我們剛才註冊的提供者。 這個已註冊的提供者的類型SqlMembershipProvider為 ,且其connectionStringName設定為適當的 連接字串 () SecurityTutorialsConnectionString ,並明確設定其applicationName值。

我們現在已準備好從應用程式使用成員資格架構。 在下一個教學課程中,我們將探討如何建立新的用戶帳戶。 接下來,我們將探索驗證使用者、執行使用者型授權,以及將其他使用者相關信息儲存在資料庫中。

快樂的程序設計!

深入閱讀

如需本教學課程中討論之主題的詳細資訊,請參閱下列資源:

本教學課程中包含的主題影片訓練

關於作者

Scott Mitchell 是多個 ASP/ASP.NET 書籍的作者,且 4GuysFromRolla.com 的作者,自 1998 年以來,已與 Microsoft Web 技術合作。 Scott 是獨立顧問、訓練員和作者。 他的最新書籍是 Sams 在 24 小時內自行 ASP.NET 2.0。 您可以在 或 透過在 的http://ScottOnWriting.NET部落格連線mitchell@4guysfromrolla.com到 Scott。

特別感謝

本教學課程系列是由許多實用的檢閱者檢閱。 本教學課程的首席檢閱者是Alicja Maziarz。 有興趣檢閱即將推出的 MSDN 文章嗎? 如果是,請將一行 mitchell@4GuysFromRolla.com放在 。