解除鎖定及核准使用者帳戶 (VB)

作者:Scott Mitchell

注意

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

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

本教學課程說明如何為系統管理員建置網頁,以管理使用者的鎖定和核准狀態。 我們也會瞭解如何在驗證其電子郵件地址之後核准新使用者。

簡介

除了使用者名稱、密碼和電子郵件之外,每個使用者帳戶都有兩個狀態欄位,指出使用者是否可以登入網站:鎖定和核准。 如果使用者在指定的分鐘數內提供不正確認證, (預設設定會在 10 分鐘內嘗試 5) 次不正確登入嘗試後鎖定使用者,就會自動鎖定使用者。 核准的狀態在某些動作必須在新使用者能夠登入網站之前進行轉譯的案例中很有用。 例如,使用者可能需要先驗證其電子郵件地址,或由系統管理員核准,才能登入。

因為鎖定或未核准的使用者無法登入,所以唯一想知道這些狀態如何重設是自然的。 ASP.NET 不包含管理使用者鎖定和核准狀態的任何內建功能或 Web 控制項,部分原因是這些決策必須依網站處理。 某些網站可能會自動核准所有新的使用者帳戶, (預設行為) 。 其他人有系統管理員核准新的帳戶,或等到他們註冊時傳送至電子郵件地址的連結,才會核准使用者。 同樣地,某些網站可能會鎖定使用者,直到系統管理員重設其狀態,而其他網站則會以他們可造訪的 URL 將電子郵件傳送給鎖定的使用者,以解除鎖定其帳戶。

本教學課程說明如何為系統管理員建置網頁,以管理使用者的鎖定和核准狀態。 我們也會瞭解如何在驗證其電子郵件地址之後核准新使用者。

步驟 1:管理使用者的鎖定和核准狀態

[建置介面以從許多教學課程中選取一個使用者帳戶] 教學課程中,我們建構了一個頁面,其中列出分頁、篩選的 GridView 中的每個使用者帳戶。 此方格會列出每個使用者的名稱和電子郵件、其核准和鎖定的狀態、他們目前是否在線上,以及使用者的任何批註。 若要管理使用者的核准和鎖定狀態,我們可以讓此方格可編輯。 若要變更使用者的核准狀態,系統管理員會先找出使用者帳戶,然後編輯對應的 GridView 資料列,核取或取消核取核准的核取方塊。 或者,我們可以透過個別 ASP.NET 網頁來管理已核准和鎖定的狀態。

在本教學課程中,我們將使用兩個 ASP.NET 網頁: ManageUsers.aspxUserInformation.aspx 。 以下概念是列出 ManageUsers.aspx 系統中的使用者帳戶,同時 UserInformation.aspx 可讓系統管理員管理特定使用者的核准和鎖定狀態。 我們的第一個業務順序是增強 GridView ManageUsers.aspx ,以包含 HyperLinkField,其會轉譯為連結的資料行。 我們希望每個連結指向 UserInformation.aspx?user=UserName ,其中 UserName 是要編輯的使用者名稱。

注意

如果您下載 [復原和變更密碼] 教學課程的程式碼 ,您可能會注意到 ManageUsers.aspx 頁面已經包含一組「管理」連結,而 UserInformation.aspx 頁面提供用來變更所選使用者密碼的介面。 我決定不要在與此教學課程相關聯的程式碼中複寫該功能,因為它的運作方式是規避成員資格 API,並直接使用 SQL Server 資料庫操作,以變更使用者的密碼。 本教學課程從頭開始與 UserInformation.aspx 頁面。

ManageUsers.aspx開啟頁面,並將 HyperLinkField 新增至 UserAccounts GridView。 分別將 HyperLinkField 的 Text 屬性設定為 「Manage」,並將其 DataNavigateUrlFieldsDataNavigateUrlFormatString 屬性分別設定為 UserName 和 「UserInformation.aspx?user= {0} 」。 這些設定會設定 HyperLinkField,讓所有超連結都顯示文字 「Manage」,但每個連結都會傳入適當的 UserName 值至 querystring。

將 HyperLinkField 新增至 GridView 之後,請花點時間透過瀏覽器檢視 ManageUsers.aspx 頁面。 如圖 1 所示,每個 GridView 資料列現在都包含「管理」連結。 Bruce UserInformation.aspx?user=Bruce 的 「管理」連結指向 ,而 Dave 的「管理」連結則指向 UserInformation.aspx?user=Dave

HyperLinkField 新增

圖 1:HyperLinkField 會為每個使用者帳戶新增「管理」連結, (按一下即可檢視完整大小的映射)

我們會在一段時間內建立 UserInformation.aspx 頁面的使用者介面和程式碼,但首先讓我們討論如何以程式設計方式變更使用者的鎖定和核准狀態。 類別 MembershipUser具有 IsLockedOutIsApproved 屬性IsLockedOut 屬性是唯讀的。 沒有以程式設計方式鎖定使用者的機制;若要解除鎖定使用者,請使用 MembershipUser 類別UnlockUser 方法。 屬性 IsApproved 是可讀取且可寫入的。 若要儲存此屬性的任何變更,我們需要呼叫 Membership 類別UpdateUser 方法,並傳入修改 MembershipUser 的物件。

IsApproved因為屬性是可讀取且可寫入的,所以 CheckBox 控制項可能是設定此屬性的最佳使用者介面元素。 不過,CheckBox 不適用於 IsLockedOut 屬性,因為系統管理員無法鎖定使用者,她只能解除鎖定使用者。 屬性的適當 IsLockedOut 使用者介面是按鈕,按一下時會解除鎖定使用者帳戶。 只有在使用者遭到鎖定時,才應該啟用此按鈕。

UserInformation.aspx建立頁面

我們現在已準備好在 中 UserInformation.aspx 實作使用者介面。 開啟此頁面並新增下列 Web 控制項:

  • 當按一下時,HyperLink 控制項會將系統管理員傳回 ManageUsers.aspx 頁面。
  • 用於顯示所選使用者名稱的標籤 Web 控制項。 將此標籤 ID 設定為 UserNameLabel ,並清除其 Text 屬性。
  • 名為 的 IsApproved CheckBox 控制項。 將其 AutoPostBack 屬性設定為 True
  • 顯示使用者上次鎖定日期的標籤控制項。 將此標籤 LastLockedOutDateLabel 命名為 ,並清除其 Text 屬性。
  • 用來解除鎖定使用者的按鈕。 將此按鈕 UnlockUserButton 命名為 ,並將其屬性設定 Text 為 「解除鎖定使用者」。
  • 顯示狀態訊息的標籤控制項,例如「使用者已更新核准的狀態」。將此控制項 StatusMessage 命名為 ,清除其 Text 屬性,並將其 屬性設定 CssClassImportant 。 (Important CSS 類別是在樣式表單檔案中 Styles.css 定義;它會在大型紅色字型中顯示對應的文字。)

新增這些控制項之後,Visual Studio 中的 [設計] 檢視看起來應該類似圖 2 中的螢幕擷取畫面。

建立 UserInformation.aspx 的使用者介面

圖 2:建立 (UserInformation.aspx 的使用者介面 ,按一下即可檢視完整大小的映射)

完成使用者介面之後,下一個工作就是根據選取的使用者資訊來設定 IsApproved CheckBox 和其他控制項。 建立頁面 Load 事件的事件處理常式,並新增下列程式碼:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
     If Not Page.IsPostBack Then
          ' If querystring value is missing, send the user to ManageUsers.aspx
          Dim userName As String = Request.QueryString("user")
          If String.IsNullOrEmpty(userName) Then
               Response.Redirect("ManageUsers.aspx")
          End If

          ' Get information about this user
          Dim usr As MembershipUser = Membership.GetUser(userName)
          If usr Is Nothing Then
               Response.Redirect("ManageUsers.aspx")

          End If

          UserNameLabel.Text = usr.UserName
          IsApproved.Checked = usr.IsApproved

          If usr.LastLockoutDate.Year < 2000 Then
               LastLockoutDateLabel.Text = String.Empty
          Else
               LastLockoutDateLabel.Text = usr.LastLockoutDate.ToShortDateString()
               UnlockUserButton.Enabled = usr.IsLockedOut
          End If
     End If
End Sub

上述程式碼一開始會確保這是第一次流覽頁面,而不是後續回傳。 然後它會讀取透過 user querystring 欄位傳遞的使用者名稱,並透過 Membership.GetUser(username) 方法擷取該使用者帳戶的相關資訊。 如果未透過 querystring 提供使用者名稱,或找不到指定的使用者,系統就會將系統管理員傳回 ManageUsers.aspx 頁面。

UserName然後,物件 MembershipUser 的值會顯示在 中 UserNameLabelIsApproved 並且會根據 IsApproved 屬性值檢查 CheckBox。

物件的 MembershipUserLastLockoutDate 屬性會傳回值, DateTime 指出使用者上次鎖定的時間。如果使用者從未遭到鎖定,則傳回的值取決於成員資格提供者。 建立新帳戶時,會將 SqlMembershipProvider 資料表的 LastLockoutDate 欄位設定 aspnet_Membership1754-01-01 12:00:00 AM 。 如果 屬性發生在 2000 年之前,上述程式碼就會在 中 LastLockoutDateLabelLastLockoutDate 顯示空字串;否則,屬性的 LastLockoutDate 日期部分會顯示在 Label 中。 UnlockUserButtonEnabled 屬性會設定為使用者的鎖定狀態,這表示只有在使用者遭到鎖定時,才會啟用此按鈕。

請花點時間透過瀏覽器測試 UserInformation.aspx 頁面。 當然,您必須從 開始 ManageUsers.aspx ,然後選取要管理的使用者帳戶。 抵達 UserInformation.aspx 時,請注意 IsApproved ,只有在使用者獲得核准時,才會檢查 CheckBox。 如果使用者已鎖定,則會顯示其上次鎖定的日期。 只有在使用者目前鎖定時,才會啟用 [解除鎖定使用者] 按鈕。核取或取消核 IsApproved 取 CheckBox 或按一下 [解除鎖定使用者] 按鈕會導致回傳,但不會修改使用者帳戶,因為我們尚未建立這些事件的事件處理常式。

返回 Visual Studio,並建立 IsApproved CheckBox CheckedChanged 事件和 UnlockUser Button 事件的 Click 事件處理常式。 CheckedChanged在事件處理常式中,將使用者的 IsApproved 屬性設定為 Checked CheckBox 的 屬性,然後透過 呼叫 Membership.UpdateUser 儲存變更。 在事件處理常式中 Click ,只要呼叫 MembershipUser 物件的 UnlockUser 方法即可。 在這兩個事件處理常式中,在標籤中 StatusMessage 顯示適當的訊息。

Protected Sub IsApproved_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles IsApproved.CheckedChanged
     'Toggle the user's approved status
     Dim userName As String = Request.QueryString("user")
     Dim usr As MembershipUser = Membership.GetUser(userName)
     usr.IsApproved = IsApproved.Checked
     Membership.UpdateUser(usr)

     StatusMessage.Text = "The user's approved status has been updated."

End Sub

Protected Sub UnlockUserButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles UnlockUserButton.Click
     'Unlock the user account
     Dim userName As String = Request.QueryString("user")
     Dim usr As MembershipUser = Membership.GetUser(userName)
     usr.UnlockUser()
     UnlockUserButton.Enabled = False

     StatusMessage.Text = "The user account has been unlocked."
End Sub

UserInformation.aspx測試頁面

有了這些事件處理常式,請重新流覽頁面並取消核准使用者。 如圖 3 所示,您應該會在頁面上看到簡短訊息,指出使用者 IsApproved 的屬性已成功修改。

Chris 已取消核准

圖 3:Chris 已取消核准 (按一下以檢視大小完整的影像)

接下來,登出並嘗試以剛未核准帳戶的使用者身分登入。 因為使用者未獲得核准,所以無法登入。 根據預設,如果使用者無法登入,則 Login 控制項會顯示相同的訊息,不論原因為何。 但在針對成員資格使用者存放區驗證使用者認證教學課程中 ,我們查看了增強登入控制項以顯示更適當的訊息。 如圖 4 所示,Chris 會顯示一則訊息,說明他因為尚未核准其帳戶而無法登入。

Chris 無法登入,因為其帳戶未經核准

圖 4:Chris 無法登入,因為其帳戶未核准 (按一下即可檢視大小完整的影像)

若要測試鎖定的功能,請嘗試以核准的使用者身分登入,但使用不正確的密碼。 重複此程式的必要次數,直到使用者帳戶遭到鎖定為止。如果嘗試從鎖定的帳戶登入,登入控制項也會更新為顯示自訂訊息。 您知道一旦開始在登入頁面上看到下列訊息,即已鎖定帳戶:「您的帳戶因為太多不正確登入嘗試而遭到鎖定。 請連絡系統管理員以解除鎖定您的帳戶。」

返回 ManageUsers.aspx 頁面,然後按一下鎖定使用者的 [管理] 連結。 如圖 5 所示,您應該會在 [解除鎖定使用者] 按鈕中看到 LastLockedOutDateLabel 應該啟用的值。 按一下 [解除鎖定使用者] 按鈕以解除鎖定使用者帳戶。 一旦您解除鎖定使用者,他們就能夠再次登入。

Dave 已鎖定系統

圖 5:Dave 已鎖定系統 (按一下以檢視大小完整的映射)

步驟 2:指定新使用者的核准狀態

核准的狀態適用于您希望在新的使用者能夠登入及存取網站使用者特定功能的案例中執行某些動作。 例如,您可能會執行私人網站,其中除了登入和註冊頁面以外,所有頁面都只能供已驗證的使用者存取。 但是,如果資訊到達您的網站、尋找註冊頁面,並建立帳戶,會發生什麼事? 若要避免發生這種情況,您可以將註冊頁面 Administration 移至資料夾,並要求系統管理員手動建立每個帳戶。 或者,您可以允許任何人註冊,但禁止網站存取,直到系統管理員核准使用者帳戶為止。

根據預設,CreateUserWizard 控制項會核准新的帳戶。 您可以使用 控制項的DisableCreatedUser 屬性來設定此行為。 將此屬性設定為 True ,以未核准新的使用者帳戶。

注意

根據預設,CreateUserWizard 控制項會自動登入新的使用者帳戶。 此行為是由控制項的LoginCreatedUser 屬性所決定。 因為未核准的使用者無法登入網站,所以當 DisableCreatedUserTrue 新的使用者帳戶未登入網站時,不論 屬性的值 LoginCreatedUser 為何。

如果您是透過 Membership.CreateUser 方法以程式設計方式建立新的使用者帳戶,若要建立未核准的 IsApproved 使用者帳戶,請使用接受新使用者屬性值做為輸入參數的其中一個多載。

步驟 3:驗證使用者的Email位址來核准使用者

許多支援使用者帳戶的網站在驗證註冊時提供的電子郵件地址之前,都不會核准新使用者。 此驗證程式通常用來阻止 Bot、垃圾郵件者和其他 ne'er-do-wells,因為它需要唯一且已驗證的電子郵件地址,並在註冊程式中新增額外的步驟。 使用此模型時,當新使用者註冊時,系統會傳送電子郵件訊息,其中包含驗證頁面的連結。 流覽使用者已證明他們收到電子郵件的連結,因此所提供的電子郵件地址有效。 驗證頁面負責核准使用者。 這可能會自動發生,因此核准任何到達此頁面的使用者,或只在使用者提供一些額外的資訊之後,例如 CAPTCHA

為了容納此工作流程,我們需要先更新帳戶建立頁面,讓新使用者未經核准。 EnhancedCreateUserWizard.aspx開啟資料夾中的頁面 Membership ,並將 CreateUserWizard 控制項的 DisableCreatedUser 屬性設定為 True

接下來,我們需要設定 CreateUserWizard 控制項,以使用如何驗證其帳戶的指示,將電子郵件傳送給新使用者。 特別是,我們會在電子郵件 Verification.aspx 中包含頁面的連結, (尚未建立) ,並透過 querystring 傳入新使用者的 UserId 。 頁面 Verification.aspx 會查閱指定的使用者,並將它們標示為已核准。

將驗證Email傳送給新使用者

若要從 CreateUserWizard 控制項傳送電子郵件,請適當地設定其 MailDefinition 屬性。 如上一 個教學課程所述,ChangePassword 和 PasswordRecovery 控制項包含MailDefinition 屬性,其運作方式與 CreateUserWizard 控制項相同。

注意

若要使用 屬性, MailDefinition 您必須在 中 Web.config 指定郵件傳遞選項。 如需詳細資訊,請參閱在 ASP.NET 中傳送Email

首先,在 資料夾中建立名為 CreateUserWizard.txtEmailTemplates 的新電子郵件範本。 針對範本使用下列文字:

Hello <%UserName%>! Welcome aboard.

Your new account is almost ready, but before you can login you must first visit:
<%VerificationUrl%>

Once you have visited the verification URL you will be redirected to the login page.

If you have any problems or questions, please reply to this email.

Thanks!

MailDefinitionBodyFileName 屬性設定為 「~/EmailTemplates/CreateUserWizard.txt」,並將其 Subject 屬性設定為 「Welcome to My Website! 請啟用您的帳戶。」

請注意, CreateUserWizard.txt 電子郵件範本包含 <%VerificationUrl%> 預留位置。 這是將放置頁面 URL Verification.aspx 的位置。 CreateUserWizard 會自動以新帳戶的使用者名稱和密碼取代 <%UserName%><%Password%> 預留位置,但沒有內 <%VerificationUrl%> 建預留位置。 我們需要以適當的驗證 URL 手動取代它。

若要達成此目的,請建立 CreateUserWizard事件的 SendingMail事件處理常式,並新增下列程式碼:

Protected Sub NewUserWizard_SendingMail(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.MailMessageEventArgs) Handles NewUserWizard.SendingMail
     'Get the UserId of the just-added user
     Dim newUser As MembershipUser = Membership.GetUser(NewUserWizard.UserName)
     Dim newUserId As Guid = CType(newUser.ProviderUserKey, Guid)

     ' Determine the full verification URL (i.e., http://yoursite.com/Verification.aspx?ID=...)
     Dim urlBase As String = Request.Url.GetLeftPart(UriPartial.Authority) & Request.ApplicationPath
     Dim verifyUrl As String = "/Verification.aspx?ID=" + newUserId.ToString()
     Dim fullUrl As String = urlBase & verifyUrl

     ' Replace <%VerificationUrl%> with the appropriate URL and querystring

     e.Message.Body = e.Message.Body.Replace("<%VerificationUrl%>", fullUrl)
End Sub

事件 SendingMail 會在事件之後引發 CreatedUser ,這表示在上述事件處理常式執行新使用者帳戶的時間已經建立。 我們可以藉由呼叫 Membership.GetUser 方法來存取新的使用者 UserId 值,並傳入 UserName 輸入至 CreateUserWizard 控制項的 。 接下來,驗證 URL 會形成。 語句 Request.Url.GetLeftPart(UriPartial.Authority) 會傳 http://yourserver.com 回 URL 的部分; Request.ApplicationPath 傳回應用程式根目錄的路徑。 然後,驗證 URL 會定義為 Verification.aspx?ID=userId 。 接著會串連這兩個字串,以形成完整的 URL。 最後,電子郵件訊息本文 (e.Message.Body) 已全部取代 <%VerificationUrl%> 為完整 URL。

淨效果是新使用者未核准,這表示他們無法登入網站。 此外,他們會自動傳送含有驗證 URL 連結的電子郵件, (請參閱圖 6) 。

新使用者會收到具有驗證 URL 連結的Email

圖 6:新使用者會收到具有驗證 URL 連結的Email, (按一下即可檢視大小完整的影像)

注意

CreateUserWizard 控制項的預設 CreateUserWizard 步驟會顯示一則訊息,告知其帳戶已建立並顯示 [繼續] 按鈕。 按一下此選項會將使用者帶至控制項 ContinueDestinationPageUrl 的 屬性所指定的 URL。 中的 EnhancedCreateUserWizard.aspx CreateUserWizard 已設定為將新使用者傳送至 ~/Membership/AdditionalUserInfo.aspx ,這會提示使用者輸入其首頁、首頁 URL 和簽章。 因為只有登入的使用者才能新增這項資訊,所以更新此屬性可將使用者傳回網站首頁 (~/Default.aspx) 。 此外, EnhancedCreateUserWizard.aspx 應該增強頁面或 CreateUserWizard 步驟,以通知使用者他們已傳送驗證電子郵件,而且除非他們遵循此電子郵件中的指示,否則不會啟用其帳戶。 我將這些修改保留為讀者的練習。

建立驗證頁面

最後一個工作是建立 Verification.aspx 頁面。 將此頁面新增至根資料夾,並將它與 Site.master 主版頁面建立關聯。 如同我們已將大部分先前的內容頁面新增至網站一樣,請移除參考 LoginContent ContentPlaceHolder 的內容控制項,讓內容頁面使用主版頁面的預設內容。

將標籤 Web 控制項新增至 Verification.aspx 頁面,將其 ID 設定為 StatusMessage ,並清除其文字屬性。 接下來,建立 Page_Load 事件處理常式並新增下列程式碼:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
     If String.IsNullOrEmpty(Request.QueryString("ID")) Then
          StatusMessage.Text = "The UserId was not included in the querystring..."
     Else
          Dim userId As Guid
          Try
               userId = New Guid(Request.QueryString("ID"))
          Catch
               StatusMessage.Text = "The UserId passed into the querystring is not in the proper format..."

               Exit Sub
          End Try

          Dim usr As MembershipUser = Membership.GetUser(userId)
          If usr Is Nothing Then
               StatusMessage.Text = "User account could not be found..."
          Else
               ' Approve the user
               usr.IsApproved = True
               Membership.UpdateUser(usr)
               StatusMessage.Text = "Your account has been approved. Please <a href=""Login.aspx"">login</a> to the site."

          End If
     End If
End Sub

上述大部分的程式碼會驗證透過 querystring 提供的 UserId 存在、它是有效的 Guid 值,以及它參考現有的使用者帳戶。 如果所有這些檢查都通過,則會核准使用者帳戶;否則會顯示適當的狀態訊息。

圖 7 顯示 Verification.aspx 流覽瀏覽器時的頁面。

新使用者的帳戶現在已核准

圖 7:新的使用者帳戶現在已核准, (按一下即可檢視完整大小的映射)

摘要

所有成員資格使用者帳戶都有兩種狀態,可判斷使用者是否可以登入網站: IsLockedOutIsApproved 。 這兩個屬性都必須 True 供使用者登入。

使用者的鎖定狀態是用來作為安全性措施,以減少駭客透過暴力密碼破解方法入侵網站的可能性。 具體而言,如果使用者在特定時間範圍內有一些不正確登入嘗試,就會遭到鎖定。 這些界限可透過 中的 Web.config 成員資格提供者設定進行設定。

核准的狀態通常用來禁止新使用者登入,直到發生某些動作為止。 或許網站需要系統管理員先核准新的帳戶,或如步驟 3 中所見,請確認其電子郵件地址。

快樂的程式設計!

關於作者

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

特別感謝...

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