共用方式為


在 SQL Server 中建立成員資格架構 (VB)

斯科特·米切爾

注意

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

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

下載程式代碼下載 PDF

本教學課程一開始會探討將必要的結構新增至資料庫中以便使用 SqlMembershipProvider 的技術。 接下來,我們將檢視資料庫架構中的主要表格,並討論它們的用途和重要性。 本教學課程的結尾在於探討如何告訴 ASP.NET 應用程式應使用哪個提供者於成員資格框架中。

介紹

之前的兩個教學課程探討了使用 Forms 驗證來識別網站訪客。 表單驗證架構可讓開發人員輕鬆地將使用者登入網站,並透過使用驗證票證,在跨頁面瀏覽時記住使用者。 FormsAuthentication 類別包含產生票證的方法,並將它新增至訪客的Cookie。 FormsAuthenticationModule 會檢查所有連入要求,對於具有有效驗證票證的要求,將建立並關聯 GenericPrincipalFormsIdentity 物件到目前要求。 表單驗證僅僅是在訪客登入時授予驗證票證的機制,並在後續的請求中解析該票證以確認使用者的身份。 若要讓 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 是 SQL Server 2005 最易讀的可存取版本:其次,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:新增一個名為 SecurityTutorials.mdf 資料庫的 SQL 資料庫至 App_Data 資料夾(點按檢視完整大小的圖片

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

SecurityTutorials 資料庫目前是空的

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

步驟 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 應用程式服務包含 SqlMembershipProviderSqlRoleProvider的架構,以及其他 ASP.NET 2.0 架構之 SQL 型提供者的架構。 我們需要將兩個資訊提供給 aspnet_regsql.exe 工具:

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

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

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

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

為了使用 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 資料庫的圖形化介面,但不會隨附於 SQL Server 2005 的 Express Edition。 好消息是,您可以下載免費的 SQL Server Management Studio Express Edition

注意

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

從關閉 Visual Studio 開始,以確保 Visual Studio 在資料庫檔案上強加的任何鎖定都已關閉。 接下來,啟動 SQL Server Management Studio 並連線到 SQL Server 2005 Express Edition localhost\InstanceName 資料庫。 如先前所述,實例名稱可能是 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 for Application Services 選項]

圖 8:選擇「設定 SQL Server for Application Services 選項」 (點擊以查看完整大小的圖片

第三個步驟會提示資料庫資訊:伺服器名稱、驗證資訊和資料庫名稱。 如果您已遵循本教學課程,並將 SecurityTutorials.mdf 資料庫新增至 App_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 時,您可以指定要安裝的特定應用程式服務元件(或移除)。 因此,如果您想要只新增 SqlMembershipProviderSqlRoleProvider 提供者所需的數據表、檢視和預存程式,請從命令行執行 aspnet_regsql.exe。 或者,您可以手動執行由 aspnet_regsql.exe所使用的 T-SQL 建立腳本子集。 這些腳本位於 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 時,我們不需要擔心低階詳細數據,例如執行哪些查詢,或 SqlMembershipProviderSqlRoleProvider修改哪些數據表。

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

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

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

用戶帳戶可能會分割到多個應用程式

圖 11:使用者帳戶可能會分割在多個應用程式之間(點擊檢視完整大小的影像

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

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

儲存用戶帳戶資訊

使用者帳戶資訊會儲存在兩個資料表中:aspnet_Usersaspnet_Membershipaspnet_Users 數據表包含保留基本用戶帳戶資訊的欄位。 三個最相關的欄位是:

  • UserId
  • UserName
  • ApplicationId

UserId 是主鍵 (且 類型為 uniqueidentifier)。 UserName 的類型是 nvarchar(256),並與密碼一起構成用戶的憑證。 (使用者的密碼儲存在 aspnet_Membership 數據表中。ApplicationId 會將用戶帳戶連結至 aspnet_Applications中的特定應用程式。 UserNameApplicationId 欄位上有複合 UNIQUE 的條件約束。 這可確保在指定的應用程式中,每個 UserName 都是唯一的,但它允許在不同的應用程式中使用相同的 UserName

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

保護密碼

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

  • Clear - 密碼會以純文字形式儲存在資料庫中。 我強烈建議不要使用此選項。 如果資料庫遭到入侵——無論是由找到後門的駭客還是不滿的員工進行的,擁有資料庫存取權——每個使用者的認證都會被取得。
  • 哈希 - 密碼會使用單向哈希演算法和隨機產生的 salt 值來哈希。 這個雜湊值(連同加鹽值)會儲存在資料庫中。
  • 加密 - 密碼的加密版本會儲存在資料庫中。

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

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

表 1 說明儲存密碼 MySecret! 時,這三個欄位在各種儲存技術中可能的樣子。 .

儲存技術<_o3a_p/> 密碼<_o3a_p/> PasswordFormat<_o3a_p /> PasswordSalt<_o3a_p />
清楚 MySecret! 0 tTnkPlesqisc2y2SMEygA==
散列 2oXm6sZHWbTHFgjgkGQsc2Ec9ZM= 1 wFgjUfhdUFOCKQiI61vtiQ==
加密 62RZgDvhxykkqsMchZ0Yly7HS6onhpaoCYaRxV8g0F4CW56OXUU3e7Inza9j9BKp 2 LSRzhGS/aa/oqAXGLHJNBw==

表格 1:儲存密碼 MySecret 時 Password-Related 欄位的範例值!

注意

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

儲存角色和角色關聯

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

  • RoleId
  • RoleName
  • ApplicationId

RoleId 是主鍵 (且 類型為 uniqueidentifier)。 RoleName 的類型為 nvarchar(256)ApplicationId 會將用戶帳戶連結至 aspnet_Applications中的特定應用程式。 RoleNameApplicationId 欄位上有複合 UNIQUE 條件約束,可確保在特定的應用程式中,每個角色名稱都是唯一的。

aspnet_UsersInRoles 資料表作為使用者和角色之間的映射。 只有兩個列 - UserIdRoleId - 並一起構成複合主鍵。

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

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

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

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

警告

您要尋找的範例看起來已經移動! 放心,我們正在努力解決這個問題。

如上述標記所示,<membership> 元素 定義 Membership 架構的組態設定,而 <providers> 子元素 則指定已註冊的提供者。 您可以使用 <add><remove> 元素來新增或移除提供者;使用 <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設定

預設 SqlMembershipProviderAspNetSqlMembershipProvider) 的 connectionStringName 屬性設定為 LocalSqlServer。 如同 AspNetSqlMembershipProvider 提供者,連接字串名稱 LocalSqlServer 定義於 machine.config中。

警告

您要尋找的範例看起來已經移動! 放心,我們正在努力解決這個問題。

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

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

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

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

警告

您要尋找的範例看起來已經移動! 放心,我們正在努力解決這個問題。

注意

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

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

警告

您要尋找的範例看起來已經移動! 放心,我們正在努力解決這個問題。

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

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

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

注意

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

總結

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

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

快樂的程序設計!

進一步閱讀

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

本教程中所涉及主題的影片訓練

關於作者

斯科特·米切爾,多個 ASP/ASP.NET 書籍的作者,4GuysFromRolla.com 的創始人,自1998年以來一直與Microsoft Web 技術合作。 斯科特擔任獨立顧問、教練和作家。 他的最新書是 《山姆教你 24 小時精通 ASP.NET 2.0》。 斯科特可以通過 mitchell@4guysfromrolla.com 或他的部落格 http://ScottOnWriting.NET聯繫。

特別感謝

本教學系列已由許多熱心的評論者審閱。 本教學課程的主要檢閱者是Alicja Maziarz。 有興趣檢閱我即將推出的 MSDN 文章嗎? 如果是,請在 mitchell@4GuysFromRolla.com給我留言。