文章目錄
- 驗證與授權
- Provider
- MembershipProvider
- 使用 Membership Provider
原文地址:http://www.odetocode.com/Articles/427.aspx
翻譯:歐盟特軟體技術公司 紀俊
很多年來,我們寫了很多代碼來實現互連網應用程式的表單瀏覽許可權管理。我們編碼來驗證使用者名稱和密碼、編碼對密碼做雜湊並校正並且編碼來建立與系統管理使用者。如果你比較兩個這種實現,你可能會發現程式結構與代碼是相似的。從 ASP.net 2.0 開始,網站開發人員不再需要寫這種重複性的代碼來儲存與驗證資訊了。取而代之的是 ASP.net 2.0 提供了 Membership Provider 與 Role Provider 作為安全與科延伸的實現來管理應用程式的角色與許可權。
驗證與授權
在這當中,Membership Provider 與 Role Provider 給我們的應用程式提供驗證與授權服務。驗證是識別使用者身份的過程。Membership Provider 可以在資料庫中建立新的使用者名稱與碼,並且通過使用儲存的資訊驗證使用者的身份。針對活動目錄也有一個 Membership Provider,不過這篇文章將會集中精力在 SQL Server Membership Provider。
ASP.net 2.0 提供了可以拖放到網頁而不用編碼就實現驗證的登陸控制項。這些控制項直接跟 Membership Provider 對話。ASP.net 2.0 也提供了控制項來維護動態使用者資訊,包括修改與重設密碼。所有這些控制項都建立在 Membership Provider 得特性之上。
一旦我們知道了使用者是誰。,我們就能明白我們允許使用者做什麼-這就是授權。ASP.net 2.0 得 Role Provider 允許我們建立角色,並且映射多個使用者到對應的角色中。舉例而言,你可能為應用程式設定兩種角色:管理員與註冊使用者。給出一個使用者名稱,Role Provider可以告訴我們這個使用者屬於哪個角色。網站應用程式程式的地區化或者特殊操作可以被限制在精確的角色裡。
當然,您的應用程式可能有特殊的需要。可能你的資料庫不是 Microsoft SQL Server。幸運的是,微軟用一種可擴充的支援模型來實現 Membership Provider 與 Role Provider。這種支援模型是 Membership Provider 與 Role Provider 服務的關鍵點,所以我們先從解釋 Provider 如果運作來展開我們的文章。
Provider
ASP.net 2.0 的 Provider 模型為開發人員提供了將他們自己的實現作為一種特性加入到運行時的可擴充方法。Membership Provider 與 Role Provider 在 ASP.net 2.0 中都通過細化一個介面或者協議來遵循 Provider 的模型。如果你建立你的組件來實現 Provider 模型定義的協議,你可以插入你的代碼到 ASP.net 運行時並且替換或者擴充已經存在的 Provider。在 ASP.net 2.0 的 Provider 模型包括一個 Provider 配置與初始化的基礎結構。
Provider 模型從抽象類別 ProviderBase 開始。ProviderBase 強迫協議為所有的 Provider 需要公用名稱與描述屬性,就像一個公用初始化方法一樣。MembershipProvider 與 RoleProvider 是繼承自 ProviderBase 的抽象類別。這些類添加額外的屬性與方法來定義它們特殊功能的介面。
舉例來說,MembershipProvider 需要一個 membership 類來實現一個 ValidateUser 方法。2.0中預設的 Membership Provider ,SqlMembershipProvider,通過在一個 SQL Server 資料庫中執行一個預存程序實現了這個方法。如果你想自己寫 Provider 是來使用 XML 檔案儲存體成員資格資訊,你將不得不自己寫 ValidateUser 的代碼來通過儲存在 XML 檔案中的資訊來驗證使用者的密碼。
Provider 模型的美妙之處在於:高層的應用程式服務可以在 Provider 上建立並且不需要知道介面之後的細節。一個很好的例子是 ASP.net 2.0 的 Membership Provider 控制項,包括 Login 控制項,CreateUser 控制項,LoginStatus 控制項等等。所有這些控制項遵循 MembershipProvider 協議。在某些時候,Login 控制項需要在配置好的 Provider 中調用 ValidateUser 方法。Login 控制項不關心是否有對 SQL Server 資料庫或者 XML 檔案的訪問。所有的 Login 控制項關心的是通過使用者名稱與密碼在傳回值中得到的是真還是假。
MembershipProvider
MembershipProvider 的作用在於在 Membership Provider 控制項之間提供一個間接層,就像 LoginControl,與成員資格資訊的資料存放區。間接意在我們可以使用任意的資料存放區(SQL Server,Oracle,XML,Web Service,Active Directory),只要我們有一個 Provider 在實體類的公用介面與屬性後隱藏細節。就像我們之前提到的,ASP.net 2.0 包括了 SQL Server 與 Active Directory 的 Provider 。
.NET 成功安裝之後會在 System.Web 裡設定 SqlMembershipProvider 類為預設的 Membership Provider。你可以在 machine.config 中找到預設的配置,這個檔案的配置對當前電腦管理的所有應用程式都有效。machine.config 檔案可以在 .net framework 安裝的配置路徑找到,典型的是\Windows\Microsoft.NET\Framework\v2.0.xxxx.
<membership>
<providers>
<add
name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, ..."
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 Provider
machine.config 中有很多跟 Membership Provider 有關的配置選項我們可以使用-它們中的需要包括使用者密碼管理。
使用 Membership Provider 的特性,您需要使用 ASP.net 2.0 中的 Login 網站控制項。CreateUser 控制項提供了擷取使用者名稱稱、密碼、電子郵件與安全問題及答案的所有的介面與實現。PasswordRecovery 控制項可以使使用者通過電子郵件重新獲得或者重設密碼。要獲得 Login 控制項的全部資訊,請參考 Securing Your Application” ASP.NET tutorials.
passwordFormat 屬性詳細說明了 Provider 怎樣儲存密碼,並且會影響許多其他 Membership Provider 的作用。SqlMembershipProvider 支援三種格式:Hashed(預設的也是最安全的格式)、Encrypted、Clear。在儲存密碼前用雜湊函數對無格式的使用者密碼與隨機值通過無法復原雜湊演算法加密,這種方法不能獲得雜湊之前的原密碼。為了驗證密碼, Provider 不得不比較雜湊之後的輸入密碼與儲存的密碼。 Provider 也可以儲存加密的密碼(這種方法可以解密並且獲得原先的值),或者儲存不經處理的密碼(這種方法不推薦使用)。
enablePasswordRetrieval 選項決定 Provider 是否可以通過 GetPassword 方法返回使用者的密碼。如果密碼格式設定為 Hashed。密碼不能重新獲得。如果 Provider 儲存的是加密的或者是未經處理的文字格式設定,你可以電郵他們忘記的使用者密碼,但是需要考慮到安全性。在密碼忘記時一個更安全的選項是重設使用者的密碼為一個新值並電郵給使用者(通過 requiresUniqueEmail 確認使用者輸入正確的電子郵件地址)。
enablePasswordReset 選項控制 ResetPassword API。ResetPassword 可以設定一個新的、自動分配的密碼給使用者。PasswordRecovery 控制項可以自動的電郵新密碼給使用者。把 requiresQuestionAndAnswer 選項設定為真來防止惡意使用者重設其他人密碼是個好方法。設定為真意味著使用者必須在重設密碼之前提供安全問題的答案。問題與答案文本在 CreateUser 控制項添加新使用者的時候需要提供。
Provider 允許很多屬性來控制密碼的強度。minRequiredPasswordLength 與 minRequiredNonalphanumericCharacters 防止使用者使用“abc”這樣簡單的密碼。如果有特殊的需求,你可以使用 passwordStrengthRegularExpression 屬性來強制密碼通過一個常規運算式測試。注意:ResetPassword 產生的密碼總是滿足密碼長度與非數字字串數量要求,但是可能不能通過常規運算式測試。
SqlMembershipProvider 提供了許多以上還沒提到的特性。例如:maxInvalidPasswordAttempts 與 passwordAttemptWindow 屬性合作可以用來防止惡意使用者暴力破解使用者的帳號。輸入錯誤台多次會使帳號被鎖定直到使用 UnlockUser 方法來解鎖。
SQL Server Membership Provider
在 Membership Provider段的其他屬性控制 SqlMemeberShipProvider 怎樣與 SQL Server 互動。預設的,machine.config 檔案配置 Membership Provider 與 Role Provider 以及使 App_data 路徑的 SQL Server Express 資料庫檔案配合。上面提到的配置,我們看到 connectionStringName 屬性是“LocalSqlServer”。如果你找到了 machine.config 連接字串段,你會發現如下資訊:
<add name="LocalSqlServer"
connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient" />
您可以覆蓋預設設定並設定所有的 Provider 使用 LocalSqlServer 或遠端資料庫或者本地的非結構化資料庫。第一步是使用 ASP.net Sql Server Registration Tool(aspnet_regsql.exe)來建立新資料庫。你可以在 .net framework 安裝路徑(WINDOWS\Microsoft.NET\Framework\2.0.xxxx)找到這個工具。如果你不使用命令列參數直接啟動工具,程式會啟動一個嚮導來建立新資料庫。預設資料庫名稱為 aspnetdb。
當你配置好了 Provider 使用的資料庫,你可以通過修改 web.config 檔案或者你的應用程式來重新定義 LocalSqlServer 連接字串來指向新資料庫。
<connectionStrings>
<remove name="LocalSqlServer"/>
<add name="LocalSqlServer"
connectionString="server=.;database=aspnetdb;integrated security=sspi;"/>
</connectionStrings>
或者,你可以定義一個新連接字串並修改 connectionStringName 屬性來使 Provider 使用新連接字串。
可以使用 ASP.net 組態工具(網站菜單下是 Visual Studio)來測試您的設定。在 Provider 欄選擇“Select a different provider for each feature”,接下來的頁面會允許您測試 Provider 的串連屬性。管理工具頁面還包括安全性、建立使用者等等功能。
Membership Provider配置的另一個重要屬性是 applicationName。applicationName 允許一個資料庫支援多個網站應用程式程式。如果有兩個網站應用程式程式並且想讓他們共用同一個使用者資料庫,給他們同一個 applicationName 屬性並且指向同一個 aspnetdb 資料庫。如果想讓他們使用同一個資料庫但是不同使用者,給他們每一個唯一的 applicationName 屬性。
使用 Membership Provider
如果想與 Membership API 直接互動,方法之一是使用 System.Web.Security 中的 Membership 類。Membership 類僅僅包括靜態成員與屬性,但是這些靜態成員在 MembershipProvider 中映射到屬性與方法,並且組件會在適當的情況下調用配置好的 Provider 。下面是一個使用編碼來實現使用者屬性的例子。
string username = "SwedishChef";
string password = "bj#kbj1k";
string email = @"swede@mailinator.com";
string question = "The greatest band ever?";
string answer = "ABBA";
bool isApproved = true;
MembershipCreateStatus status;
Membership.CreateUser(
username, password, email,
question, answer, isApproved,
out status);
if(status == MembershipCreateStatus.Success)
{
// party!
}
一個早期的Membership Provider 介面使用 ASP.net 2.0 Login 控制項:Login 、LoginView、PasswordRecovery、LoginStatus、LoginName、CreateUserWizard與ChangePassword。Login 控制項,舉例而言,當使用者輸入他們的使用者名稱與密碼並且點擊登陸按鈕時會使用當前Membership Provider 的 ValidateUser 方法。如果內建控制項提供了所有您所需的功能,不需要編寫任何代碼。所有的控制項可以被設定為各種風格通過樣式與模板。在 Visual Studio 工具條的“Login”分類下可以找到這些控制項。