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

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