由 斯科特·米切爾
註解
自本文撰寫以來,ASP.NET 成員資格提供者已被 ASP.NET Identity取代。 強烈建議更新應用程式以使用 ASP.NET 身分識別 平臺,而不是本文撰寫時精選的成員資格提供者。 ASP.NET 身分識別在 ASP.NET 成員資格系統中有許多優點,包括:
- 更好的效能
- 改善擴充性和可測試性
- 支援 OAuth、OpenID Connect 和雙因素驗證
- 宣告型身分識別支援
- 與「ASP.Net Core」更好的互操作性
本教學課程一開始會探討將必要架構新增至資料庫以使用 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 隨附兩個內建成員資格提供者:ActiveDirectoryMembershipProvider 和 SqlMembershipProvider。 正如其名稱所暗示,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 架構新增至此資料庫;在後續的教學課程中,我們將建立其他數據表來擷取應用程式數據。
圖 1:將一個名為 SecurityTutorials.mdf 資料庫的新 SQL Database 新增至 App_Data 資料夾(按一下即可查看完整大小的影像)
將資料庫新增至 App_Data 資料夾會自動包含在 [資料庫總管] 檢視中。 (在非 Express Edition 版本的 Visual Studio 中,資料庫總管稱為 [伺服器總管]。移至 [資料庫總管],然後展開剛新增 SecurityTutorials 資料庫。 如果您沒有在畫面上看到 [資料庫總管],請移至 [檢視] 功能表並選擇 [資料庫總管],或按 Ctrl+Alt+S。 如圖 2 所示,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 應用程式服務包含 SqlMembershipProvider 和 SqlRoleProvider的架構,以及其他 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。
InstanceName 最有可能是 SQLExpress。 不過,如果您手動安裝 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 驗證]。
圖 3:連線到 SQL Server 2005 Express Edition 實例(按兩下即可檢視完整大小的映像)
聯機到 SQL Server 2005 Express Edition 實例之後,Management Studio 會顯示資料庫的資料夾、安全性設定、伺服器物件等等。 如果您展開 [資料庫] 索引標籤,您會看到 SecurityTutorials.mdf 資料庫 未在資料庫實例中註冊 -我們需要先附加資料庫。
以滑鼠右鍵按兩下 [資料庫] 資料夾,然後從操作選單中選擇 [附加]。 這會顯示 [附加資料庫] 對話框。 從這裡按兩下 [新增] 按鈕,流覽至 SecurityTutorials.mdf 資料庫,然後按下 [確定]。 圖 4 顯示選取 SecurityTutorials.mdf 資料庫之後的 [附加資料庫] 對話框。 圖 5 顯示成功附加資料庫之後 Management Studio 的物件總管。
圖 4:附加 SecurityTutorials.mdf 資料庫 (按兩下即可檢視完整大小的影像)
圖 5:SecurityTutorials.mdf 資料庫會出現在 [資料庫] 資料夾中(按兩下即可檢視完整大小的影像)
如圖 5 所示,SecurityTutorials.mdf 資料庫的名稱相當荒謬。 讓我們將其變更為更令人難忘且更容易輸入的名稱。 以滑鼠右鍵單擊資料庫,從操作功能表中選擇 [重新命名],並將它重新命名 SecurityTutorialsDatabase。 這不會變更檔名,只是資料庫用來向 SQL Server 識別本身的名稱。
圖 6:將資料庫重新命名為 SecurityTutorialsDatabase(按兩下即可檢視完整大小的影像)
此時,我們分別知道 SecurityTutorials.mdf 資料庫檔案的伺服器和資料庫名稱:localhost\InstanceName 和 SecurityTutorialsDatabase。 我們現在已準備好透過 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 所示,說明工具的用途。
圖 7:使用 ASP.NET SQL Server 安裝精靈 來新增成員資格架構(按兩下即可檢視完整大小的影像)
精靈中的第二個步驟會詢問我們是否要新增應用程式服務或移除它們。 由於我們希望新增 SqlMembershipProvider所需的資料表、檢視表和預存程序,請選擇「為應用程式服務配置 SQL Server」選項。 稍後,如果您想要從資料庫移除此架構,請重新執行此精靈,但改為選擇 [從現有的資料庫移除應用程式服務資訊] 選項。
圖 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 並導覽至 [Database Explorer]。 展開 [數據表] 資料夾。 您應該看到一系列的資料表,其名稱的字首為 aspnet_。 同樣地,您可以在 [檢視] 和 [預存程式] 資料夾下找到各種檢視和預存程式。 這些資料庫物件組成應用程式服務架構。 我們將在步驟 3 中檢查成員資格和角色特定的資料庫物件。
圖 10:已將各種數據表、檢視表和預存程式新增至資料庫(按兩下即可檢視完整大小的影像)
注意
aspnet_regsql.exe 工具的圖形使用者介面會安裝整個應用程式服務架構。 但是,從命令行執行 aspnet_regsql.exe 時,您可以指定要安裝的特定應用程式服務元件(或移除)。 因此,如果您想要只新增 SqlMembershipProvider 和 SqlRoleProvider 提供者所需的數據表、檢視和預存程式,請從命令行執行 aspnet_regsql.exe。 或者,您可以手動執行由 aspnet_regsql.exe所使用的 T-SQL 建立腳本子集。 這些腳本位於 WINDIR%\Microsoft.Net\Framework\v2.0.50727\ 資料夾中,名稱如 InstallCommon.sql、InstallMembership.sql、InstallRoles.sql、InstallProfile.sql、InstallSqlState.sql等等。
此時,我們已建立 SqlMembershipProvider所需的資料庫物件。 不過,我們仍然需要指示成員資格架構應使用 SqlMembershipProvider 而非 ActiveDirectoryMembershipProvider,並且 SqlMembershipProvider 應該使用 SecurityTutorials 資料庫。 我們將探討如何指定要使用的提供者,以及如何在步驟 4 中自定義所選提供者的設定。 但首先,讓我們更深入地查看剛建立的資料庫物件。
步驟 3:查看架構的核心數據表
在 ASP.NET 應用程式中使用成員資格和角色架構時,提供者會封裝實作詳細數據。 在未來的教學課程中,我們將透過 .NET Framework 的 Membership 和 Roles 類別來與這些架構互動。 使用這些高階 API 時,我們不需要擔心低階詳細數據,例如執行哪些查詢,或 SqlMembershipProvider 和 SqlRoleProvider修改哪些數據表。
鑒於此,我們可以放心地使用成員資格和角色架構,而不需要探索在步驟 2 中建立的資料庫架構。 不過,建立數據表來儲存應用程式數據時,可能需要建立與使用者或角色相關的實體。 在為應用程式數據表與步驟 2 中創建的數據表之間設立外鍵約束時,熟悉 SqlMembershipProvider 和 SqlRoleProvider 架構會有所幫助。 此外,在某些罕見情況下,我們可能需要直接在資料庫層級與使用者和角色互動(而不是透過 Membership 或 Roles 類別)。
將使用者存放區分割成應用程式
成員資格和角色架構的設計可讓單一使用者和角色存放區在許多不同的應用程式之間共用。 使用成員資格或角色架構的 ASP.NET 應用程式必須指定要使用的應用程式分割區。 簡言之,多個 Web 應用程式可以使用相同的使用者和角色存放區。 圖 11 描述分割成三個應用程式的使用者和角色存放區:HRSite、CustomerSite 和 SalesSite。 這三個 Web 應用程式各自有自己的唯一使用者和角色,但它們都會在相同的資料庫數據表中實際儲存其用戶帳戶和角色資訊。
圖 11:使用者帳戶可能會分割在多個應用程式之間(點擊以查看全尺寸圖片)
aspnet_Applications 表是用來定義這些分割區的。 使用此資料庫來儲存使用者帳戶資訊的每個應用程式,都會以此數據表中的數據列來表示。
aspnet_Applications 資料表有四個資料行:ApplicationId、ApplicationName、LoweredApplicationName和 Description。
ApplicationId 的類型為 uniqueidentifier,而且是數據表的主鍵;ApplicationName 為每個應用程式提供唯一的易記名稱。
其他成員資格和角色相關數據表會連結回 aspnet_Applications中的 [ApplicationId] 字段。 例如,aspnet_Users 資料表中包含每個用戶帳戶的記錄,並具有 ApplicationId 外鍵欄位;aspnet_Roles 資料表也是如此。 這些數據表中的 [ApplicationId] 字段會指定使用者帳戶或角色所屬的應用程式分割區。
儲存用戶帳戶資訊
使用者帳戶資訊會儲存在兩個資料表中:aspnet_Users 和 aspnet_Membership。
aspnet_Users 數據表包含保留基本用戶帳戶資訊的欄位。 三個最相關的欄包括:
UserIdUserNameApplicationId
UserId 是主鍵 (且 類型為 uniqueidentifier)。
UserName 的類型為 nvarchar(256),並與密碼一起構成用戶的認證。 (使用者的密碼儲存在 aspnet_Membership 數據表中。ApplicationId 會將用戶帳戶連結至 aspnet_Applications中的特定應用程式。
UserName 和 ApplicationId 數據行上有複合 UNIQUE 條件約束。 這可確保在指定的應用程式中,每個 UserName 都是唯一的,但它允許在不同的應用程式中使用相同的 UserName。
aspnet_Membership 數據表包含其他使用者帳戶資訊,例如使用者的密碼、電子郵件位址、上次登入日期和時間等等。
aspnet_Users 和 aspnet_Membership 數據表中的記錄之間有一對一的對應。
aspnet_Membership中的 [UserId] 字段可確保此關聯性,其做為數據表的主鍵。 如同 aspnet_Users 數據表,aspnet_Membership 包含 ApplicationId 欄位,將此資訊系結至特定應用程式分割區。
保護密碼
密碼信息會儲存在 aspnet_Membership 數據表中。
SqlMembershipProvider 允許使用下列三種技術之一,將密碼儲存在資料庫中:
- Clear - 密碼會以純文字形式儲存在資料庫中。 我強烈建議不要使用此選項。 如果資料庫被破解—無論是駭客找到後門還是擁有資料庫存取權的不滿員工—每個使用者的認證都可能被盜取。
- 哈希 - 密碼會使用單向哈希演算法和隨機產生的 salt 值來哈希。 這個哈希值(連同鹽值)會儲存在資料庫中。
- 加密 - 密碼的加密版本會儲存在資料庫中。
所使用的密碼儲存技術取決於 Web.config中指定的 SqlMembershipProvider 設定。 我們將探討在步驟 4 中自定義 SqlMembershipProvider 設定。 默認行為是儲存密碼的哈希。
負責儲存密碼的資料列是 Password、PasswordFormat和 PasswordSalt。
PasswordFormat 是類型為 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_Roles 和 aspnet_UsersInRoles。
aspnet_Roles 數據表中的每個記錄都代表特定應用程式的角色。 與 aspnet_Users 數據表類似,aspnet_Roles 數據表有三個與討論相關的數據行:
RoleIdRoleNameApplicationId
RoleId 是主鍵 (且 類型為 uniqueidentifier)。
RoleName 的類型為 nvarchar(256)。
ApplicationId 會將用戶帳戶連結至 aspnet_Applications中的特定應用程式。
RoleName 和 ApplicationId 欄上有複合 UNIQUE 條件約束,可確保在指定的應用程式內,每個角色名稱都是唯一的。
aspnet_UsersInRoles 數據表可作為使用者和角色之間的對應。 只有兩個欄位 - UserId 和 RoleId - 共同組成複合主鍵。
步驟 4:指定提供者並自定義其設定
支援提供者模型的所有架構,例如成員資格和角色架構,都缺乏實作詳細數據,而是會將該責任委派給提供者類別。 在成員資格架構的情況下,Membership 類別會定義用來管理用戶帳戶的 API,但不會直接與任何使用者存放區互動。 相反地,Membership 類別的 方法會將要求移交給設定的提供者 , 我們將使用 SqlMembershipProvider。 當我們在 Membership 類別中叫用其中一個方法時,成員資格架構如何知道如何將呼叫委派給 SqlMembershipProvider?
Membership 類別具有 Providers 屬性,其中包含所有已註冊提供者類別的參考,供成員資格架構使用。 每個已註冊的提供者都有相關聯的名稱和類型。 此名稱提供人類易記的方式來參考 Providers 集合中的特定提供者,而型別則會識別提供者類別。 此外,每個已註冊的提供者可能包含組態設定。 成員資格架構的組態設定包括 passwordFormat 和 requiresUniqueEmail等等。 如需 SqlMembershipProvider所使用的組態設定完整清單,請參閱表 2。
Providers 屬性的內容是透過 Web 應用程式的組態設定來指定。 根據預設,所有 Web 應用程式都有一個名為 AspNetSqlMembershipProvider,類型為 SqlMembershipProvider的提供者。 這個預設成員資格提供者會在 machine.config 中註冊(位於 %WINDIR%\Microsoft.Net\Framework\v2.0.50727\CONFIG):
警告
您要尋找的範例看起來已經移動! 放心,我們正在努力解決這個問題。
如上述標記所示,<membership> 元素 定義了 Membership 架構的組態設定,而 <providers> 子元素 指定已註冊的提供者。 您可以使用 <add> 或 <remove> 元素來新增或移除提供者;使用 <clear> 元素來移除所有目前已註冊的提供者。 如上述標記所示,machine.config 新增了一個名為 AspNetSqlMembershipProvider 且類型為 SqlMembershipProvider的提供者。
除了 name 和 type 屬性之外,<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 |
密碼儲存格式:Clear、Hashed或 Encrypted。 預設值為 Hashed。 |
passwordStrengthRegularExpression |
如果提供,則會使用此正則表達式來評估使用者在建立新帳戶或變更其密碼時所選取密碼的強度。 預設值為空字串。 |
requiresQuestionAndAnswer |
指定使用者在擷取或重設密碼時,是否必須回答其安全性問題。 預設值為 true。 |
requiresUniqueEmail |
指出指定應用程式分割區中的所有用戶帳戶是否都必須有唯一的電子郵件位址。 預設值為 true。 |
type |
指定提供者的類型。 此值是必要的。 |
表 2:成員資格和 SqlMembershipProvider 組態設定
除了 AspNetSqlMembershipProvider之外,其他會員資格提供者也可以註冊於每個應用程式,方法是將類似的標記新增至 Web.config 檔案。
注意
角色架構的運作方式大致相同:machine.config 中有預設的已註冊角色提供者,而且在 Web.config中,可以依應用程式自定義已註冊的提供者。 我們將在未來的教學課程中詳細檢查角色架構及其組態標記。
自訂SqlMembershipProvider設定
預設 SqlMembershipProvider (AspNetSqlMembershipProvider) 的 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中的第一個提供者,除非另有指示,否則它會作為預設提供者。
目前,我們的應用程式有兩個已註冊的提供者:AspNetSqlMembershipProvider 和 SecurityTutorialsSqlMembershipProvider。 不過,在註冊 SecurityTutorialsSqlMembershipProvider 提供者之前,我們可以藉由在 <add> 元素之前立即新增 <clear /> 元素,以清除所有先前註冊的提供者。 這會從已註冊的提供者清單中清除 AspNetSqlMembershipProvider,這表示 SecurityTutorialsSqlMembershipProvider 是唯一已註冊的成員資格提供者。 如果我們使用此方法,則不需要將 SecurityTutorialsSqlMembershipProvider 標示為預設提供者,因為它是唯一已註冊的成員資格提供者。 如需有關使用 <clear />的更多資訊,請參閱 使用 <clear /> 新增提供者。
請注意,SecurityTutorialsSqlMembershipProvider中的 connectionStringName 設定會引用剛新增的 SecurityTutorialsConnectionString 連接字串名稱,並且其 applicationName 設定已被設為 SecurityTutorials 的值。 此外,requiresUniqueEmail 設定已設定為 true。 所有其他組態選項都與 AspNetSqlMembershipProvider中的值相同。 如果您想要的話,您可以在這裡進行任何設定修改。 例如,您可以藉由要求兩個非英數位元而不是一個字元,或將密碼長度增加到八個字元,而不是七個字元,來加強密碼強度。
注意
回想一下,成員資格架構可讓單一使用者存放區跨多個應用程式進行分割。 成員資格提供者的 applicationName 設定會指出提供者在處理使用者存放區時所使用的應用程式。 請務必明確設定 applicationName 組態設定的值,因為如果未明確設定 applicationName,則會在運行時間指派給 Web 應用程式的虛擬根路徑。 只有在應用程式的虛擬根路徑不變更的情況下,運作會正常。但如果您將應用程式移至不同的路徑,則 applicationName 設定也會變更。 當這種情況發生時,成員資格提供者將開始使用不同於之前使用的應用程式分割區。 在移動之前建立的使用者帳戶會位於不同的應用程式分割區中,而且這些使用者將無法再登入網站。 如需有關此事的更深入討論,請參閱 務必設定 applicationName 屬性於設定 ASP.NET 2.0 成員資格和其他提供者時。
總結
此時,我們有一個資料庫具有已設定的應用程式服務(SecurityTutorials.mdf),並已設定我們的 Web 應用程式,讓成員資格架構使用我們剛才註冊的 SecurityTutorialsSqlMembershipProvider 提供者。 這個已註冊的提供者的類型為 SqlMembershipProvider,且其 connectionStringName 設定為適當的連接字串(SecurityTutorialsConnectionString),並明確設定其 applicationName 值。
我們現在已準備好從應用程式使用成員資格架構。 在下一個教學課程中,我們將檢查如何建立新的用戶帳戶。 接下來,我們將探索驗證使用者、執行使用者型授權,以及將其他使用者相關信息儲存在資料庫中。
快樂的程序設計!
進一步閱讀
如需本教學課程中所討論主題的詳細資訊,請參閱下列資源:
-
在設定 ASP.NET 2.0 成員資格和其他提供者時,一律設定
applicationName屬性 - 將 ASP.NET 2.0 應用程式服務設定為使用 SQL Server 2000 或 SQL Server 2005
- 下載 SQL Server Management Studio
- 檢查 ASP.NET 2.0 的成員資格、角色和使用者設定檔
-
提供者的會員資格
<add>元素 -
<membership>元素 -
<providers>的成員資格元素 - 當新增提供者 時,使用
-
直接使用
SqlMembershipProvider
本教學課程中包含主題的訓練影片
關於作者
斯科特·米切爾,多個 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留言。