實作成員資格提供者

更新:2007 年 11 月

ASP.NET 成員資格的設計目的是要讓您能夠輕鬆使用許多 ASP.NET 應用程式不同成員資格提供者。您可以使用 .NET Framework 中提供的成員資格提供者,或者也可以實作自己的提供者。

建立自訂成員資格提供者的主要理由共有兩個。

  • 您需要將成員資格資訊儲存於 .NET Framework 中包含的成員資格提供者所不支援的資料來源,例如 FoxPro 資料庫、Oracle 資料庫或其他資料來源。

  • 您在管理成員資格資訊時所需要使用的資料庫結構描述,不同於提供者 (隨附於 .NET Framework) 所使用的資料庫結構描述。這個情況的常見例子是已經存在於公司或網站的 SQL Server 資料庫中的成員資格資料。

必要的類別

若要實作成員資格提供者,請您建立繼承 MembershipProvider 抽象類別的類別 (此抽象類別來自 System.Web.Security 命名空間)。MembershipProvider 抽象類別繼承來自 System.Configuration.Provider 命名空間的 ProviderBase 抽象類別,所以您必須也要實作 ProviderBase 類別的必要成員。下列表格列出您必須從 ProviderBaseMembershipProvider 抽象類別實作的必要屬性及方法,並且提供每一項的說明。若要檢閱每位成員的實作,請參閱提供給成員資格提供者實作範例的程式碼。

必要的 ProviderBase 成員

成員

描述

Initialize 方法

採用提供者的名稱和組態設定的 NameValueCollection 當做輸入。用來設定提供者執行個體的屬性值,其中包括組態所提供的組態檔 (Machine.config 或 Web.config) 中指定的實作相關值和選項。

必要的 MembershipProvider 成員

成員

描述

EnablePasswordReset 屬性

在組態檔 (Web.config) 中指定的 Boolean 值。

EnablePasswordReset 屬性指示使用者是否可以使用 ResetPassword 方法,以隨機產生的新密碼覆寫目前的密碼。

這個屬性是唯讀的。

EnablePasswordRetrieval 屬性

在組態檔 (Web.config) 中指定的 Boolean 值。

EnablePasswordRetrieval 屬性指示使用者是否可以使用 GetPassword 方法來擷取密碼。

這個屬性是唯讀的。

RequiresQuestionAndAnswer 屬性

在組態檔 (Web.config) 中指定的 Boolean 值。

RequiresQuestionAndAnswer 屬性指示使用者是否必須要提供密碼回應,才能使用 GetPassword 方法來擷取密碼或使用 ResetPassword 方法來重設密碼。

這個屬性是唯讀的。

RequiresUniqueEmail 屬性

在組態檔 (Web.config) 中指定的 Boolean 值。

RequiresUniqueEmail 屬性指示當使用者在建立其他使用者時,是否必須要提供唯一的電子郵件地址值。如果使用者已存在於目前 ApplicationName 的資料來源中,則 CreateUser 方法傳回 null (在 Visual Basic 中為 Nothing) 以及 DuplicateEmail 的狀態值。

這個屬性是唯讀的。

PasswordFormat 屬性

在組態檔 (Web.config) 中指定的 MembershipPasswordFormat 值。

PasswordFormat 屬性指示密碼儲存的格式。密碼可以儲存在以下的密碼格式:Clear、Encrypted 和 Hashed。Clear 密碼以純文字格式儲存,此格式可增進儲存和擷取密碼的效率但安全性較低,若資料來源洩露時,密碼容易被讀取。Encrypted 在儲存時已加密,並且可在比對密碼或擷取密碼時解密。在儲存和擷取密碼時,這需要進行額外的處理但安全較高,若資料來源洩露時,不容易判斷密碼。當 Hashed 密碼儲存於資料庫中時,它會使用單向雜湊演算法和隨機產生的 Salt 值來進行雜湊。驗證密碼時,它會以資料庫中的 Salt 值來雜湊以進行驗證。雜湊的密碼無法擷取。

您可以使用 MembershipProvider 類別的 EncryptPasswordDecryptPassword 虛擬方法來對密碼值進行加密及解密,或者您可以提供自己的加密程式碼。如果使用 MembershipProvider 類別的 EncryptPasswordDecryptPassword 虛擬方法,Encrypted 密碼會使用組態中 machineKey 項目 (ASP.NET 設定結構描述) 所提供的金鑰資訊來進行加密。

這個屬性是唯讀的。

MaxInvalidPasswordAttempts 屬性

在組態檔 (Web.config) 中指定的 Integer 值。

MaxInvalidPasswordAttemptsPasswordAttemptWindow 搭配使用,可防止不適當的對象重複嘗試猜測成員資格使用者的密碼或密碼回應。如果成員資格使用者提供的密碼或密碼問題無效,且在 PasswordAttemptWindow 所識別的分鐘數內其次數超過 MaxInvalidPasswordAttempts,成員資格使用者會因 IsLockedOut 屬性設為 true 而遭鎖定,直到使用 UnlockUser 方法才能解除鎖定。如果在達到 MaxInvalidPasswordAttempts 之前提供有效的密碼或密碼回應,追蹤無效嘗試次數的計數器會重設為零。

如果 RequiresQuestionAndAnswer 屬性設為 false,則不會追蹤無效的密碼回應嘗試。

無效的密碼嘗試與密碼回應嘗試會在 ValidateUserChangePasswordChangePasswordQuestionAndAnswerGetPasswordResetPassword 方法中進行追蹤。

這個屬性是唯讀的。

PasswordAttemptWindow 屬性

在組態檔 (Web.config) 中指定的 Integer 值。

如需說明,請參閱 MaxInvalidPasswordAttempts 屬性的描述。

這個屬性是唯讀的。

ApplicationName 屬性

使用組態檔 (Web.config) 中指定之成員資格資訊的應用程式名稱。ApplicationName 與相關的使用者資訊一同儲存於資料來源中,並於查詢該資訊時使用。如需詳細資訊,請參閱稍後這個主題中的 ApplicationName 章節。

這個屬性為讀取/寫入,如果無明確指定則預設值為 ApplicationPath

CreateUser 方法

接受輸入新使用者的名稱、密碼和電子郵件地址,並且將應用程式的新使用者插入資料來源中。CreateUser 方法傳回 MembershipUser 物件,此物件會填入新建立之使用者的資訊。CreateUser 方法同時還定義 out 參數 (在 Visual Basic 中,您可使用 ByRef),此參數傳回 MembershipCreateStatus 值,表示是否成功建立使用者,或無法成功建立使用者的原因。

如果 MembershipValidatePasswordEventHandler 已指定,CreateUser 方法會引發 ValidatingPassword 事件,並且根據事件結果繼續或取消建立使用者之動作。您可以使用 OnValidatingPassword 虛擬方法來執行指定的 MembershipValidatePasswordEventHandler

UpdateUser 方法

接受輸入 MembershipUser 物件,該物件是以使用者資訊填入,並以所提供的值更新資料來源。

DeleteUser 方法

接受輸入使用者的名稱,並從資料來源刪除使用者的資訊。如果成功刪除使用者,DeleteUser 方法傳回 true,否則傳回 false。而且另外還包含 Boolean 參數,表示使用者的相關資訊 (例如角色或設定檔資訊) 是否也被刪除。

ValidateUser 方法

採用使用者名稱和密碼當做輸入,並且驗證這兩個值是否符合資料來源中的值。如果使用者名稱和密碼成功的相符,ValidateUser 方法傳回 true,否則傳回 false。

GetUser 方法

採用唯一的使用者識別項和 Boolean 值當做輸入,此值指示是否要更新使用者的 LastActivityDate 值,以顯示使用者目前已在線上。GetUser 方法傳回 MembershipUser 物件,此物件從資料來源填入指定使用者的目前值。如果資料來源中找不到使用者名稱,GetUser 方法則傳回 null (在 Visual Basic 中為 Nothing)。

GetUser 方法

採用使用者名稱和 Boolean 值當做輸入,此值指示是否要更新使用者的 LastActivityDate 值,以顯示使用者目前已在線上。GetUser 方法傳回 MembershipUser 物件,此物件從資料來源填入指定使用者的目前值。如果資料來源中找不到使用者名稱,GetUser 方法則傳回 null (在 Visual Basic 中為 Nothing)。

GetAllUsers 方法

傳回 MembershipUserCollection,其填入資料來源中所有使用者的 MembershipUser 物件。

GetAllUsers 傳回的結果受到 pageIndex 和 pageSize 參數限制。pageSize 參數辨識 MembershipUser 物件的最大數量,並以 MembershipUserCollection 將其傳回。pageIndex 參數會識別要傳回哪一個結果頁面,1 代表第一頁。totalRecords 參數是一個 out 參數,其設定為成員資格使用者的總數。例如,如果此應用程式有 13 位使用者在資料庫中,且 pageIndex 值為 2,而 pageSize 為 5,則傳回的 MembershipUserCollection 將包含傳回的第 6 至 第 10 位使用者。而 totalRecords 將設為 13。

GetNumberOfUsersOnline 方法

傳回整數數值,此值為資料來源中 LastActivityDate 大於目前日期與時間減去 UserIsOnlineTimeWindow 屬性的使用者計數。UserIsOnlineTimeWindow 屬性是一個整數數值,其指定在判斷使用者是否在線上時所使用的分鐘數。

ResetPassword 方法

接受輸入使用者名稱和密碼解答,並為指定的使用者隨機產生新的密碼。ResetPassword 方法以新的密碼值來更新資料來源中的使用者資訊,並且將新密碼當做 string 傳回。產生隨機密碼的便利機制為 Membership 類別中的 GeneratePassword 方法。

ResetPassword 方法可確保 EnablePasswordReset 屬性在執行任何動作前已設為 true。如果 EnablePasswordReset 屬性為 false,便會擲回 NotSupportedExceptionResetPassword 方法也會檢查 RequiresQuestionAndAnswer 屬性值。如果 RequiresQuestionAndAnswer 屬性為 true,ResetPassword 方法會根據資料來源中儲存的密碼回應,檢查提供的回應參數值。如果兩者不相符,便會擲回 MembershipPasswordException

如果 MembershipValidatePasswordEventHandler 已指定,ResetPassword 方法則會引發 ValidatingPassword 事件,以驗證新產生的密碼,並且根據事件結果繼續或取消重設密碼之動作。您可以使用 OnValidatingPassword 虛擬方法來執行指定的 MembershipValidatePasswordEventHandler

GetPassword 方法

採用使用者名稱和密碼回應當做輸入,並且從資料來源擷取該使用者的密碼,然後將密碼當做 string 傳回。

GetPassword 可確保 EnablePasswordRetrieval 屬性在執行任何動作前已設為 true。如果 EnablePasswordRetrieval 屬性為 false,便會擲回 ProviderException

GetPassword 方法也會檢查 RequiresQuestionAndAnswer 屬性值。如果 RequiresQuestionAndAnswer 屬性為 true,GetPassword 方法會根據資料來源中儲存的密碼回應,檢查提供的回應參數值。如果兩者不相符,便會擲回 MembershipPasswordException

GetUserNameByEmail 方法

接受輸入電子郵件地址,並傳回資料來源中的第一個使用者名稱,其電子郵件地址與提供的 email 參數值相符。

如果找不到電子郵件地址相符的使用者名稱,將會傳回空字串。

如果有數個符合特定電子郵件地址的使用者名稱,則僅傳回第一個找到的使用者名稱。

ChangePassword 方法

接受輸入使用者名稱、目前的密碼,以及新密碼,而且如果所提供的使用者名稱和目前的密碼有效,就更新資料來源中的密碼。如果成功更新密碼,ChangePassword 方法傳回 true,否則傳回 false。

如果 MembershipValidatePasswordEventHandler 已指定,ChangePassword 方法會引發 ValidatingPassword 事件,並且根據事件結果繼續或取消變更密碼的動作。您可以使用 OnValidatingPassword 虛擬方法來執行指定的 MembershipValidatePasswordEventHandler

ChangePasswordQuestionAndAnswer 方法

採用使用者名稱、密碼、密碼問題和密碼回應當做輸入,而且如果提供的使用者名稱及密碼有效,則更新資料來源中的密碼問題和密碼回應。如果成功更新密碼問題和密碼回應,ChangePasswordQuestionAndAnswer 方法傳回 true,否則傳回 false。

如果提供的使用者名稱和密碼無效,則會傳回 false。

FindUsersByName 方法

傳回成員資格使用者名單,其使用者名稱在設定的 ApplicationName 中包含與提供之 usernameToMatch 相符的字串。例如,如果 usernameToMatch 參數設定為 "user",則將傳回 "user1"、"user2"、"user3" 等,以此類推。萬用字元的支援是根據資料來源所提供。使用者是以使用者名稱字母順序傳回。

FindUsersByName 傳回的結果受到 pageIndex 和 pageSize 參數限制。pageSize 參數辨識 MembershipUser 物件的數量,並以 MembershipUserCollection 將其傳回。pageIndex 參數會識別要傳回哪些結果頁面,1 代表第一頁。totalRecords 參數是一個 out 參數,其設定為符合 usernameToMatch 值的成員資格使用者的總數。例如,如果共有 13 人的使用者名稱部分或全部符合 usernameToMatch,且 pageIndex 值為 2,而 pageSize 為 5,則 MembershipUserCollection 將會包含傳回的第 6 至第 10 位使用者。而 totalRecords 將設為 13。

FindUsersByEmail 方法

傳回成員資格使用者名單,其使用者名稱在設定的 ApplicationName 中包含與提供之 emailToMatch 相符的字串。例如,如果 emailToMatch 參數設定為 "address@example.com",則將傳回的使用者其電子郵件地址將會是 "address1@example.com"、"address2@example.com" 等,以此類推。萬用字元的支援是根據資料來源所提供。使用者是以使用者名稱字母順序傳回。

FindUsersByEmail 傳回的結果受到 pageIndex 和 pageSize 參數限制。pageSize 參數辨識 MembershipUser 物件的數量,並以 MembershipUserCollection 將其傳回。pageIndex 參數會識別要傳回哪些結果頁面,1 代表第一頁。totalRecords 參數是一個 out 參數,其設定為符合 emailToMatch 值的成員資格使用者的總數。例如,如果共有 13 人的使用者名稱部分或全部符合 emailToMatch,且 pageIndex 值為 2,而 pageSize 為 5,則 MembershipUserCollection 將會包含傳回的第 6 至第 10 位使用者。而 totalRecords 將設為 13。

UnlockUser 方法

接受輸入使用者名稱,並更新將 IsLockedOut 屬性儲存為 false 之資料來源中的欄位。如果成功更新成員資格使用者的記錄,UnlockUser 方法傳回 true,否則傳回 false。

ApplicationName

成員資格提供者會為每一應用程式儲存唯一的使用者資訊。這可讓多重 ASP.NET 應用程式使用相同的資料來源,即使建立了重複的使用者名稱也不會產生衡突。或者,多重 ASP.NET 應用程式可藉由指定相同的 ApplicationName 來使用同一使用者資料來源。

由於成員資格提供者為每一應用程式儲存唯一的使用者資訊,因此您將必須確認資料結構描述、查詢以及更新中務必包含應用程式名稱。例如,下列程式碼是用來根據電子郵件地址從資料庫擷取使用者名稱,同時確認查詢中包含 ApplicationName

SELECT Username FROM MyUserTable 
  WHERE Email = 'someone@example.com' AND ApplicationName = 'MyApplication'

自訂成員

您可能需要擴充成員資格提供者介面,使其具有 ProviderBaseMembershipProvider 抽象類別不提供的其他功能。任何加入至成員資格提供者的 Public 成員將可使用 Membership 類別的 ProviderProviders 屬性來存取。

其中一個例子便是 LockUser 方法,它可將 IsLockedOut 屬性設為 true。以下範例顯示如何將公開應用程式之預設資格成員提供者的 Provider 屬性轉換為自訂提供者類型,以便呼叫自訂的 LockUser 方法。

Dim p As MyCustomProvider = CType(Membership.Provider, MyCustomProvider)
p.LockUser(username)
MyCustomProvider p = (MyCustomProvider)Membership.Provider;
p.LockUser(username);

執行緒安全

ASP.NET 會針對應用程式在組態中所指定的每個成員資格提供者,具現化單一成員資格提供者執行個體,其用於由 HttpApplication 物件服務的所有要求。因此,您可以同時執行多個要求。ASP.NET 並不確保對提供者呼叫的執行緒安全。您需要將提供者程式碼撰寫成具備執行緒安全。例如,建立資料庫連接或開啟檔案來編輯應該是在呼叫像是 CreateUser 成員的期間完成,而不是在呼叫 Initialize 方法時開啟檔案或資料庫連接。

請參閱

概念

成員資格提供者實作範例

設定 ASP.NET 網站巡覽的安全性

參考

ValidatePasswordEventArgs

OnValidatingPassword

其他資源

使用成員資格管理使用者

保護 ASP.NET 網站