本文英文原版及代碼下載:
http://aspnet.4guysfromrolla.com/articles/120705-1.aspx
考察ASP.NET 2.0Membership,Roles,Profile - Part 1
導言:
很多網站都有一個共同點:提供用戶帳號(user accounts),這些網站允許(或需要)訪問者創建帳號以使用特定的功能.比如ASPMessageboard.com網站,匿名用戶和注冊用戶都可以使用搜索功能,但如果要發表文章或回復消息的話,訪問者就必須獲得用戶帳號并登錄網站.
一個支持用戶帳號的網站,都要包括這些相同的步驟:創建一個數據庫表來存儲用戶帳號信息;創建一個登錄頁面;定義一種系統,當頁面回傳時仍可保存注冊用戶的登錄狀態;指出哪些頁面只對注冊用戶可見;創建一個新頁面供新用戶注冊;創建一個頁面便于網站管理員管理用戶帳號等等.在ASP.NET之前,開發者必須決定如何貫徹這些方面。ASP.NET引入了forms-based authentication的概念,二樓提供了一個FormsAuthentication class類來便于在網站登錄或注銷.同樣的還有authentication ticket,在頁面請求時保存用戶的登錄狀態。(關于ASP.NET的基于窗體的識別功能,請參閱文章《Using Forms Authentication in ASP.NET 》和《Dissecting Forms Authentication》)
即便有了基于窗體的識別功能,ASP.NET開發者仍然要定義并構建相應的結構來存儲用戶帳號信息;創建登錄和注銷的web頁面;還有便于訪問者創建新帳號和便于管理員管理帳號的頁面等.感謝ASP.NET 2.0,利用其membership system 和 security Web控件,可以減輕開發者的負擔.簡單的說,membership是一個API,可以編程訪問與用戶帳戶相關的任務.比如:有專門的方法創建一個新的用戶帳戶,識別用戶身份,刪除用戶,返回所有的用戶信息等.此外,還有很多建立在該API基礎上的security Web控件.
本系列文章將考察2.0版本中的membership, roles,pofile系統,以及各種security Web控件.本文我們考察membership的基本原理并配置與使用內置的SqlMembershipProvider.
基于窗口的認證(Authentication)
在ASP.NET之前,web開發者必須自己定義所有的認證.一個問題是當頁面請求時如何記住用戶的登錄狀態,也就是說當用戶輸入用戶名和密碼并成功登錄后,當用戶訪問其它頁面時,網站如何記得該用戶是否成功登錄了?另一個問題是如何防止頁面被未授權的用戶訪問,也就是說如何設置一個頁面只能被一部分或被授權的用戶訪問?在經典ASP里我們通過使用Session變量來解決這些問題.每個頁面檢查該Session變量一確定訪問者的身份,以及是否允許他們訪問.
為此,ASP.NET 1.0版提供了對forms-based authentication的支持,同時可以在Web.config文件里指定authorization rules角色.forms-based authentication提供了一種方法將authentication ticket作為一個cookie存儲在瀏覽器里,在發生web請求的時候記住用戶的登錄狀態.而FormsAuthentication class類包含了很多方法來處理這些authentication ticket。可以創建它也可以刪除它.
不幸的是forms-based authentication依然留給開發者很多工作.開發者仍然必須決定如何傳遞用戶帳戶信息;仍然必須構建登錄頁面并編寫使用FormsAuthentication class類的代碼;仍然必須構建注銷頁面;構建注冊帳戶頁面;構建管理帳戶的頁面等等。ASP.NET 1.0版本引入forms-based authentication的初衷是好的,只是貫徹起來有難度.
在Forms-Based Authentication之上構建ASP.NET 2.0的Membership
Forms-based authentication依然存在于ASP.NET 2.0版本,使用方法與 1.x版本一樣。同時在Web.config文件里也有authorization設置. ASP.NET 2.0版本增加的是membership API以及security Web控件.
membership API是通過provider模式來執行的.那就意味著當定義好界面后可以對實際的執行過程進行定制.而.NET Framework包含了Membership class類,該類包含可很多方法,比如 CreateUser(), GetAllUsers(), ValidateUser()等等. 然而,當通過一個ASP.NET web應用程序來使用API的時候實際調用的類取決于應用程序的配置.你可以定制你的用戶帳戶邏輯,方法是創建一個執行定義好的membership API的類,然后配置web應用程序來使用你定義的類.當然,你也用不著定義一個自定義的類——ASP.NET包含了2個內置的membership providers,一個將用戶帳戶信息存儲在一個SQL Server數據庫;另一個使用的是實際的目錄.因此membership system 和 security Web控件都可以被這2個內置的providers使用.如果你確實自定義了用戶數據,你也可以創建一個自定義的provider通過相同的API 和 security控件來使用這些自定義的用戶數據.關于provider模式的更多信息,請參閱文章《A Look at ASP.NET 2.0's Provider Model》(
http://aspnet.4guysfromrolla.com/articles/101905-1.aspx
)
在本系列的后續文章里,我們將考察創建用戶自定義的membership provider的詳細步驟.
SqlMembershipProvider——將用戶帳戶數據存儲在一個SQL Server數據庫
ASP.NET 2.0 里的SqlMembershipProvider provider使用一個數據庫來存儲認證信息.為了使用該provider,你必須創建一個相應的數據庫構架(schema).可以通過2種方法來完成:
1.使用ASP.NET網站管理工具(這將會在一個SQL Server 2005數據庫文件ASPNETDB.mdf里創建構架,且位于App_Data文件夾)
2.使用ASP.NET SQL Server注冊工具——使用該工具在一個SQL Server 2000 或 2005 數據庫里創建構架.
圖1
要使用ASP.NET網站管理工具的話,首先在Visual Studio的Website菜單,選擇“ASP.NET Configuration”項,然后在Security項里,將authentication類型改為"From the internet" 。具體方法是:要么點"Select authentication type"鏈接,要么點" "Use the security Setup Wizard to configure security step by step"鏈接.這樣將自動在App_Data文件夾里創建一個名為ASPNETDB.mdf的數據庫(我們馬上將考察該數據庫的構架).關于使用網站管理工具的更多詳情請參閱文章《Website Administration Tool Overview》(
http://msdn2.microsoft.com/en-us/library/yy40ytx0.aspx
)
如果你大算將用戶帳號信息存儲在其它地方——比如App_Data文件夾之外的一個SQL Server 2000 或SQL Server 2005數據庫. 那么你就需要使用ASP.NET SQL Server注冊工具(aspnet_regsql.exe).該工具具有圖像界面,當然你也可以通過命令行來使用它.你可以借助于圖像界面指定在什么地方添加所需要的表.關于使用該工具的更多詳情,請參閱技術文檔( http://msdn2.microsoft.com/en-us/library/ms229862.aspx )
注意:
當你使用ASP.NET網站管理工具來將authentication類型設置為"From the internet" ,這將在Web.config文件里添加一行:
<authentication mode="Forms" />
如果你通過ASP.NET SQL Server注冊工具來創建數據庫構架的話,你必須手工向Web.config文件添加在行。此外,沒有在App_Data文件夾里的ASPNETDB.mdf數據庫里創建構架,而是在其它數據庫創建的,那么你必須要在Web.config文件里定制membership配置,并指定連接數據庫的連接字符串.
SqlMembershipProvider將用戶帳戶信息存儲在下面2個表里:
.aspnet_Users -每一個用戶帳戶一條記錄,存儲最基本的信息.其UserId列唯一的標識用戶身份.
.aspnet_Membership—該表的UserId列將該表與aspnet_Users表里的某條特定記錄對應起來.aspnet_Membership表存儲的是與用戶帳號相關的數據: Email, Password, 安全提示問題以及答案等等.
定制SqlMembershipProvider
如果你希望使用SqlMembershipProvider的默認配置(那就意味著用戶帳戶信息存儲在App_Data文件夾里的ASPNETDB.mdf數據庫里),那么你除了在Web.config文件里指定使用到的窗體認證和授權角色(authorization rules)外,不需要做其它的更改.(對于窗體認證和授權角色問題,可以通過ASP.NET網站管理工具來指定。關于在Web.config文件里指定authorization配置的更多信息請參閱文章《 Authentication and Authorization》(
http://samples.gotdotnet.com/quickstart/aspplus/doc/authandauth.aspx
)和文章《Authorizing Users and Roles》(
http://samples.gotdotnet.com/quickstart/aspplus/doc/authorization.aspx
)
如果你打算使用另外一個數據庫,或者說改變membership的某些配置(比如:email地址是否是唯一的;密碼的最短長度; 密碼是純文本還是經過加密;安全提示問題和答案是不是必需的等等)的話,你就要在Web.config文件里手動輸入XML模塊來指定你自己的用戶配置.(注意:你必須要為applicationName設置一個“硬編碼”值,有關這方面的更多詳情請參閱《Always set the "applicationName" property when configuring ASP.NET 2.0 Membership and other Providers》)
下面的XML代碼顯示了如何定制SqlMembershipProvider設置。具體來說,屬于黑體字的XML在<membership>元素里對設置進行定制。在其上還有一個<connectionString>節點,提供了連接到數據庫的連接字符串(我們可以推算出來,該數據庫構架是使用ASP.NET SQL注冊工具添加的) :
<configuration>
<connectionStrings>
<add name="MyDB" connectionString="..." />
</connectionStrings>
<system.web>
... authentication & authorization settings ...
<membership defaultProvider="CustomizedProvider">
<providers>
<add name="CustomizedProvider"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="MyDB"
applicationName="ScottsProject"
minRequiredPasswordLength="5"
minRequiredNonalphanumericCharacters="0" />
</providers>
</membership>
</system.web>
</configuration>
ASP.NET 2.0包含了一個內置的名為LocalSqlServer的連接字符串,它指向 App_Data文件夾里的ASPNETDB數據庫.如果你希望使用默認的ASPNETDB數據庫,并只改變一些屬性.將connectionStringName配置為LocalSqlServer.
在<membership>元素里添加一個名為CustomizedProvider的新provider,并作為默認的membership provider.該自定義provider仍然使用SqlMembershipProvider ;將connectionStringName設置為MyDB(就是在<connectionStrings>節點指定的);將applicationName設置為ScottsProject;將minRequiredPasswordLength設置為5;將minRequiredNonalphanumericCharacters設置為0.我們只是對很少的屬性進行自定義設置,全部屬性清單見《<add> Element for Providers for Membership》。
Security Web控件的簡單概述
Security Web控件為處理與用戶帳戶相關的的任務提供了一個用戶界面.主要包括7種security user控件:
Login控件——該控件呈現為標準的username/password登錄界面.默認下,當用戶點擊"Login"按鈕時,立即產生頁面回傳,控件調用Membershipclass類的VerifyUser(username, password)方法來對用戶進行驗證,如果驗證通過則為用戶創建一個authentication ticket,否則顯示一個出錯信息.
為LoginError event事件創建事件處理器,便于當用戶為通過驗證時自定義處理步驟;為Authenticate event事件創建事件處理器,以執行你個人的驗證邏輯;Login控件包含了很多的屬性供配置,以改變用戶界面的外觀.要完善控件,可以使用LayoutTemplate,下面的截屏為Login控件的默認用戶界面:
LoginView控件:有時我們希望根據訪問者是匿名用戶還是登錄用戶來顯示不同的內容:比如,當一個匿名用戶訪問主頁時你可能希望顯示一個Login Web控件,而如果是一個登錄用戶的話,我們希望顯示一個消息,比如:"Welcome back, username" ,再附加一個注銷的鏈接.
LoginView控件提供了2個模板:AnonymousTemplate 和 LoggedInTemplate模板.將顯示給匿名用戶的Web控件和HTML標記放在AnonymousTemplate模板里;而將顯示給登錄用戶看的放在LoggedInTemplate模板;此外該控件還可以根據登錄者角色的不同顯示不同的界面.
PasswordRecovery控件-允許用戶重新獲取現有的密碼或將一個新密碼傳遞到用戶的電子郵件地址.如果密碼在存儲時經過哈希算法處理,那么“重新獲取”密碼實際上是創建一個新的隨機的密碼,再送回給你.如果密碼是純文本或經過加密處理,那么將把現有密碼送回給用戶.
LoginStatus控件—如果是匿名用戶,該控件將顯示一個轉到登錄頁面的連接;如果是登錄用戶將顯示一個注銷鏈接.
LoginName控件——該控件僅僅將登錄用戶的username顯示出來。另外,可以通過User.Identity.Name,編程訪問用戶的名稱.
CreateUserWizard控件——除了登錄的頁面外,我們還需要一個供訪問者注冊的頁面。而CreateUserWizard控件就提供了創建用戶帳號所需的用戶界面,當用戶輸入必需的數據并點"Create User"按鈕時,將調用Membership class類的 CreateUser(...)方法.如果需要的話,可以用templates對CreateUserWizard控件進行定制.下面的截屏為運行中的CreateUserWizard控件.
同樣可以對CreateUserWizard控件的布局和參數進行定制,詳情見《Customizing the CreateUserWizard Control》( http://aspnet.4guysfromrolla.com/articles/070506-1.aspx )
ChangePassword控件——該控件允許用戶改變其密碼
所有的security Web控件在使用的時候可以不用寫一行代碼。比如你要創建一個登錄頁面,你只需要創建一個Login.aspx頁面并拖一個Login控件到頁面上。瞧,就這么簡單,不用寫一行代碼。此外security Web控件包含了豐富的事件模型,你可以編程處理各種不同的事件.在本文的下載內容里包含了幾個頁面演示如何使用這些控件.
編程使用Membership System
可以通過Membership class類來使用membership system的函數,比如: GetAllUsers(), CreateUser(), DeleteUser()等等.你可以通過security Web控件在使用這些方法,也可以直接從ASP.NET頁面調用這些方法.比如你可以創建一個頁面來列出所有的用戶,方法是將Membership.GetAllUsers()返回的結果綁定到一個GridView控件上。在本文下載內容里有幾個編程使用Membership class類的示例.
結語:
由于很多網站需要用戶帳號支持,所以ASP.NET對該功能的支持是很有意義的.不過在ASP.NET 1.0版本里面,本目標只達到了一半。雖然基于窗口的驗證提供了標準的手段包含一個authentication ticket來維系用戶的登錄狀態,但無法存儲用戶帳戶信息或創建必要的web頁面(比如:登錄、創建帳戶等等)。在2.0版本,ASP.NET包含了membership服務和一些security Web控件.以彌補1.x版本的不足.
在本文,我們考察了membership system的注意目標,一個其中一個內置的membership providers——SqlMembershipProvider.該SqlMembershipProvider將用戶帳戶信息存儲在一個SQL Server數據庫,我們也可以通過Web.config文件對其進行用戶定制。此外我們還總覽了ASP.NET的security Web控件.它用來執行登錄、創建用戶帳戶,以及其他與用戶帳戶相關的用戶界面元素.
除了membership system外,ASP.NET 2.0還包含了roles 和 profile system.我們將在后面的文章探討它們.
祝編程快樂!
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
