我編譯了許多 Microsoft® asp.net 應用程序,例如客戶端應用程序和原型、我自己不斷增長的站點和幫助不會編程的家人和朋友所開發的站點,以及文章、演示文稿和培訓課程的代碼。我經常發現自己在編譯每個應用程序時,總有某些重復的任務要做,這其中很大一部分是定義驗證模型。保護應用程序資源幾乎是設計任何應用程序時必不可少的一項工作。ASP.NET 1.x 讓事情變得簡單了些,它提供了一個頗為簡單和安全的、基于表單的驗證進程,但您仍要糾纏于角色管理和其他工作之中。如果每設計一個新登錄表單可以掙 5 美分,那么我現在至少已經掙了 10 多美元,算一算,我設計了多少個表單。即將發行的新版本 ASP.NET 的開發代號是“Whidbey”(與即將發行的新版本 Microsoft® Visual Studio® .NET 的開發代號一致),它提供了許多新的配置工具、控件和組件,以支持用于驗證用戶和管理受保護資源的完整系統。這些新功能十分直觀易用,即使您的祖母也能在一天內構建一個安全站點。
按照傳統做法,為新 Web 站點構建一個驗證模型通常包括以下步驟:
即使只是構建幾個可重復使用的組件來封裝上述某些重復性任務,您仍會感到肩上的工作負擔減輕了不少。ASP.NET Whidbey 的新組件大大減少了上述步驟中的五個步驟的工作量,至少將其減少為了原來工作量的一部分。我將使用新的基于 Web 的管理向導來自動創建一組表,以處理用戶、角色和權限。在同一個管理界面中,我還會就登錄、成員身份和角色管理對應用程序進行配置。我將在一秒鐘(或者說僅僅是在 Web 表單中拖放一個登錄控件的時間)之內設計出一個登錄頁面,而且我根本不用編寫一行用于驗證用戶或關聯角色的代碼,因為這些會自動完成。根據用戶角色和登錄狀態的不同,呈現的菜單和頁面內容也將不同,但我同樣無需為此編寫任何代碼。
是不是有夢想成真的感覺?讓我們看看這是如何實現的。
ASP.NET Whidbey 包括一個新的基于 Web 的配置工具,它運行于特定應用程序的上下文中,這樣便可以通過交互的方式來修改應用程序自身的 web.config 文件。該工具帶有許多向導,其中一個可以引導您完成設置安全選項的全部步驟。使用 Visual Studio“Whidbey”完成新 Web 站點的創建后,您可以通過兩種方法啟動該配置工具:從“Solution Explorer”(解決方案資源瀏覽器)中選擇“ASP.NET Configuration”(ASP.NET 配置)圖標或從“Website”(站點)菜單中選擇“ASP.NET Configuration”(ASP.NET 配置)。
圖 1:從“Solution Explorer”(解決方案資源瀏覽器)或主菜單啟動基于 Web 的配置實用工具。
配置 Web 界面啟動時會顯示一個查詢字符串,指示要配置的應用程序目標。在本文中,我創建了一個名為“MySecureNewsletter”的新應用程序,并啟動了管理界面,如下所示:
圖 2:在我的計算機上啟動管理界面的 URL 是 http://localhost:10245/ASP.NETWebAdminFiles/default.aspx?applicationPhysicalPath=H:/WebSites/MySecureNewsletter/&applicationUrl=/MySecureNewsletter。
“Security”(安全)選項卡中的一個選項是運行“Security Setup Wizard”(安全設置向導)。對于一個新應用程序,應當首先運行該向導。向導界面的左側面板顯示了將要逐步執行的步驟列表,并指出您當前所在的步驟:
圖 3:安全設置向導使用 ASP.NET Whidbey 的某些其他很酷的功能,例如用于導航的向導控件。
設置過程中的步驟非常簡單,所以在此僅概述我為示例應用程序所選的選項。首先,向導詢問我該站點是 Intranet 站點還是 Internet 站點。前者默認使用 Windows 驗證,后者(也是我的選擇)將把應用程序配置為使用表單驗證。下一步,向導顯示創建數據庫以存儲用戶和角色的選項。如果選擇此選項,向導將詢問我是選擇創建 Microsoft access 數據庫還是創建 Microsoft SQL Server™ 數據庫,然后引導我完成幾個附加的步驟。我沒有選擇這個選項,所以在應用程序的 /Data 目錄下將創建一個默認的 Access 數據庫。在 machine.config 文件中,<connectionString>
元素指定了 Access 數據庫的默認位置:
<connectionStrings> <add name="LocalSqlServer" connectionString="data source=127.0.0.1;Integrated Security=SSPI" /> <add name="AccessFileName" connectionString="~/DATA/ASPNetDB.mdb" /> </connectionStrings>
下一步,我啟用了該應用程序的角色管理。此時,將創建帶有大量表格的默認 Access 數據庫,并且最終將由新的安全控件和成員身份 API 來使用這些表。此時,我可以選擇創建角色和用戶。創建每個角色時都需要使用簡單的字符串值,如下所示:
圖 4:界面左側的向導面板顯示我正在對應用程序的安全模型執行哪一步設置。
要創建用戶,需要設想一下您可能希望為每個用戶收集哪些字段,特別是用戶名、密碼、電子郵件、說明和可選密碼問題及答案。如果已創建了任何角色,則這些角色顯示為復選框選項的形式以供選擇:
圖 5:此處輸入的電子郵件字段以后將用于與用戶進行交互,例如在用戶取回密碼時。
通過以上幾個簡單的步驟,我們已在 /Data 目錄下創建了一個新數據庫(文件名為 AspNetDB.mdb),用于存儲成員身份信息。刷新“Solution Explorer”(解決方案資源瀏覽器)以后,您還可以看到已創建了一個 web.config 文件,用于啟用 <roleManager>
設置中的角色管理。這一步是必需的,因為 machine.config 中的默認設置是禁用角色管理。新的 web.config 文件如下所示:
<?xml version="1.0" encoding="utf-8"?><configuration> <system.web> <roleManager enabled="true"> <PRoviders /> </roleManager> </system.web></configuration>
在以上數個簡短的步驟中,我創建了標準的成員身份和憑據管理數據庫,角色和用戶也創建完畢,并完成了角色管理必需的 Web 配置,現在我們就可以構建一個安全的應用程序了。
如果沒有在第一次配置過程中完成角色和用戶的創建,您可以隨時返回到該配置工具輸入或修改設置,但我現在將演示如何創建自己的管理頁面。
到文章的本節為止,您依然不需要編寫任何代碼。我將演示如何使用 ASP.NET Whidbey 的新安全控件來生成一個基于角色的可行的驗證系統。我將從我的示例電子通訊應用程序 MySecureNewsletter 開始。目前,除了我剛剛在向導中完成的步驟以外,尚未生成任何安全模型。順便說一句,這個應用程序使用了 Whidbey 新的“母版頁”功能。關于該功能的詳細信息,請參閱 Master Pages in ASP.NET Whidbey(英文)。在“Solution Explorer”(解決方案資源瀏覽器)中,您將看到 /templates 目錄下包含可重復使用的用戶控件和母版頁模板,而 /images 目錄存儲所有支持圖形,根目錄下則有一些應用程序頁面。
圖 6:示例應用程序中的所有 *.aspx 頁面都將使用一個母版頁作為布局模板。內容頁面和 Web 表單頁面一樣,但前者指定了母板頁模板,且所有的內容都放在內容控件中。
添加名為 login.aspx 的新內容頁面以后,我們可以開始享受些樂趣了?!癟oolbox”(工具箱)帶有“Security”(安全)選項卡,其中列出了 ASP.NET Whidbey 中與安全性相關的非??岬男驴丶?。
圖 7:“ToolBox”(工具箱)已經針對 ASP.NET Whidbey 進行了重新組織,新的安全控件將集中到它們自己的選項卡上。
我將從剛剛拖放到新的 login.aspx 頁面上的“Login”(登錄)控件開始,一個個地瀏覽這些安全控件:
圖 8:登錄控件提供了編輯控件默認布局的交互式設計器界面。
您可以選擇某一個“AutoFormat”(自動套用格式)選項來為控件外觀選擇一個已封裝的格式:
圖 9:目前有兩個已封裝格式可用,但如果應用程序使用了默認樣式表,您還可以通過“Properties”(屬性)窗口為控件的各個元素指定樣式。
“Properties”(屬性)窗口還提供了對控件各個元素的標記、值和驗證錯誤消息的訪問。您也可以自定義登錄按鈕的外觀,并提供創建新成員的鏈接。現在,讓我們看看使用可信任的樣式表和控件默認選項會生成些什么??丶傻脑创a如下所示:
<asp:login id="Login1" runat="server"></asp:login>
這樣,我的登錄頁面就完成了。因為我已經配置了應用程序的用戶和角色,所以我僅需修改 web.config 文件,把驗證模式設置為“Forms”(表單),因為默認方式是“Windows”驗證。同時,為了測試登錄進程,我還將拒絕匿名用戶:
<authentication mode="Forms"/><authorization> <deny users="?" /> </authorization>
注意:我早先曾提及安全設置向導將應用程序配置為使用表單驗證,該向導是通過生成默認數據庫以存儲憑據來完成該配置的。該向導并不是(在 Whidbey Alpha 版本中)通過修改應用程序的 web.config 文件中的 <authentication> 設置來指定如上所示的表單驗證模式。
現在,系統將引導所有的匿名用戶前往登錄頁面(幸好使用了母版頁和樣式表,在花了一秒鐘將登錄控件拖動到表單后,這個頁面看起來還過得去):
圖 10:在沒有修改任何屬性的情況下,這是在頁面模板中顯示的登錄控件的默認外觀。
如果輸入了有效的用戶名和密碼,“Log In”(登錄)按鈕將自動驗證用戶,并將其重定向到最初請求的頁面。當然,登錄以后,習慣上要為用戶顯示個性化的歡迎頁面,并提供注銷的途徑。我將把這兩個功能添加到顯示在每個頁面中的 menus.ascx 用戶控件?!癓oginName”(登錄名)控件顯示了已驗證的用戶名,而“LoginStatus”(登錄狀態)控件則提供了一個方便的超級鏈接,它會根據當前驗證狀態,在登錄和注銷操作之間切換。以下是將這兩個新控件添加到 menus.ascx 文件的適當位置后的 HTML 源代碼:
當前您已登錄為: <asp:loginname id="LoginName1" runat="server"></asp:loginname><asp:loginstatus id="LoginStatus1" runat="server"></asp:loginstatus>
噢,這太粗略了?,F在有了登錄頁面,讓我們看看用戶登錄以后顯示的個性化歡迎頁面,同時我們還為用戶提供了注銷的途徑,所有這些都不需要編寫代碼。
圖 11:在 Login(登錄)/Logout(注銷)之間切換
登錄名控件只執行一個任務:顯示已驗證用戶的名稱。默認情況下,登錄狀態控件自動在 Login(登錄)/Logout(注銷)之間切換,但可以使用模板進一步自定義。注銷的實際進程也由該控件進行封裝。
關于此個性化歡迎頁面的唯一問題是:在登錄之前,頁面會顯示空白用戶名,我們可能需要編寫一些代碼來控制這一部分。不過,也許我們同樣可以不用編寫代碼就能做到。
如果使用以前的 ASP.NET 版本來顯示當前已驗證的用戶,我們需要編寫代碼來訪問當前上下文的用戶標識。要僅在用戶驗證后顯示該信息,還需要編寫更多的代碼來檢查用戶的狀態。“LoginView”(登錄視圖)控件可能是最有意思的新安全控件之一,它讓我們能夠基于驗證狀態和角色來控制頁面內容。為了檢驗這一點,我向 menu.ascx 文件添加了一個登錄視圖控件。通過與設計環境進行交互,您可以編輯希望匿名用戶(尚未登錄)或已驗證用戶所看到的信息。
圖 12:“Common LoginView Tasks”(通用登錄視圖任務)使您可以在視圖之間切換,或通過單擊“Edit Templates”(編輯模板)超級鏈接開始編輯模板。
您始終可以通過“Source”(源文件)視圖直接修改 HTML。以下代碼顯示了向 menus.ascx 文件的個性化歡迎頁面中添加登錄視圖控件時所做的修改:
<asp:loginview id="LoginView1" runat="server"> <anonymoustemplate> 您目前尚未登錄。 </anonymoustemplate> <loggedintemplate> 當前您已登錄為:<asp:loginname id="LoginName1" runat="server"> </asp:loginname> </loggedintemplate></asp:loginview>
登錄視圖控件在用戶尚未通過驗證時顯示 <anonymoustemplate>
節的內容,用戶通過驗證后顯示 <loggedintemplate>
節的內容。所以,沒有編寫任何代碼,我們已利用安全控件為用戶提供了登錄頁面、注銷功能、個性化歡迎頁面和基于驗證狀態的自定義頁面內容。
您肯定會覺得難以置信,自動管理密碼就是如此簡單?!癙assWordRecovery”(密碼取回)控件提供了功能完善的密碼取回系統,包括基于密碼問題查找密碼以及自動重設密碼,并通過電子郵件將密碼發送給用戶。我在應用程序根下創建了密碼取回頁面,在將密碼取回控件拖放到頁面后,我看到了以下內容:
圖 13:“Common PasswordRecovery Tasks”(通用密碼取回任務)使您可以自定義該過程中的每一步驟的外觀。
密碼管理設計的大量活動都是可以配置的。例如,您可以要求用戶創建密碼問題和答案,并將其作為密碼安全模型的一部分。PasswordRecovery 控件包括這樣一個界面,要求用戶回答他們在創建帳號時提供的密碼問題。如下所示,您可以編輯密碼取回的每一部分的設置,包括請求用戶名、詢問密碼問題,以及完成該過程后顯示對用戶的響應。
圖 14:密碼問題和答案的形式可由成員身份提供程序(本文稍后將介紹)進行配置。
此控件自動重設密碼,并將新密碼發送到用戶的電子郵件帳號。生成的電子郵件的屬性可通過控件的公共屬性進行配置。在示例程序中,我自定義了電子郵件的主題標題和發件人的地址。所生成的 HTML 如下所示:
<asp:passwordrecovery id="Passwordrecovery1" runat="server"> <maildefinition bodyformat="Html" subject="Password Recovery for MySecureNewsletter" from="mailto:mailadmin@dotnetdashboard.com"> </maildefinition> </asp:passwordrecovery>
如果正確地配置了用于發送電子郵件的 SMTP 服務器,我將接收到包含新密碼的電子郵件:
圖 15:通過在“Properties”(屬性)窗口中設置“BodyFilename”和“BodyFormat”屬性,可以提供電子郵件的 HTML 模板。
在示例中,我使用自己的 SMTP 服務器測試了該功能,而您將在 web.config 文件中看到 SMTP 設置的這個示例:
<smtpMail serverName="smtp.mysmtpserver.com" serverPort="25"> </smtpMail>
這是一個奇妙的功能,為處理密碼管理提供了快速的安全方案。但對于大型站點,您很可能希望進一步了解組件的體系結構。例如,您希望確保生成電子郵件的組件具有可伸縮性,您還可能想編寫一些代碼來控制如何通過電子郵件向成員發送密碼:也許是提供對顯示解密密碼的已過期 Web 頁面的鏈接。
大多數應用程序依賴角色來控制對資源的訪問、信息顯示方式和可允許的活動。此前,我創建過許多用戶,并使用安全管理工具來為其指定角色。如果是在 ASP.NET 的以前版本中使用這些角色,我就得編寫代碼,以從已驗證的用戶的憑據存儲中手動檢索角色。LoginView 控件通過配置的成員身份提供程序(或者是成員身份 API)與這些角色進行交互,并支持為任何有效角色提供內容模板。
假定我將把一組僅能由管理員訪問的管理頁面添加到應用程序。如果向標題中一個“Admin”(管理)菜單項,我很可能希望其僅對管理員顯示。為了實現這一點,我將把另一個登錄視圖控件添加到菜單界面。LoginView 控件的某個屬性(可通過“Properties”[屬性] 窗口訪問)支持通過對話框界面將角色列表添加到“RoleGroups”(角色組)集合:
圖 16:“RoleGroup Collection Editor”(角色組集合編輯器)要求手動輸入角色。您也可以為角色編組,這樣多個組可以共享同樣的模板界面。
在“Design”(設計)視圖中,LoginView 控件現在將角色列表顯示為模板選項:
圖 17:“HTML”視圖將更新,顯示您為每個角色所設計的所有模板。
從以下 HTML 源文件中可以看出,“Admin”(管理)和“Member”(成員)角色使用了新的內容模板。在驗證以前仍將使用 <anonymoustemplate>
,但驗證以后,將使用與某個用戶角色匹配的第一個模板。如果未找到匹配項,默認使用 <loggedintemplate>
設置。
<asp:loginview id="lvMenu" runat="server"> <anonymoustemplate> <asp:loginstatus id="anonLoginStatus" runat="server"> </asp:loginstatus> </anonymoustemplate> <rolegroups> <asp:rolegroup roles="Admin"> <contenttemplate> <tr> <td class="OtherTabs"> <asp:hyperlink id="adminHome" runat="server" navigateurl="~/default.aspx">Home</asp:hyperlink> | </td> <td class="OtherTabs"> <asp:hyperlink id="adminAbout" runat="server" navigateurl="~/about.aspx">About</asp:hyperlink> | </td> <td class="OtherTabs"> <asp:hyperlink id="adminAdmin" runat="server" navigateurl="~/admin/manageMembers.aspx">Admin </asp:hyperlink> | </td> <td class="OtherTabs"> <asp:loginstatus id="adminLoginStatus" runat="server"> </asp:loginstatus> </td> </tr> </contenttemplate> </asp:rolegroup> <asp:rolegroup roles="Member"> <contenttemplate> <tr> <td class="OtherTabs"> <asp:hyperlink id="memberHome" runat="server" navigateurl="~/default.aspx">Home</asp:hyperlink> | </td> <td class="OtherTabs"> <asp:hyperlink id="memberAbout" runat="server" navigateurl="~/about.aspx">About</asp:hyperlink> | </td> <td class="OtherTabs"> <asp:loginstatus id="memberLoginStatus" runat="server"> </asp:loginstatus> </td> </tr> </contenttemplate> </asp:rolegroup> </rolegroups> <loggedintemplate> <tr> <td class="OtherTabs"> <asp:hyperlink id="authHome" runat="server" navigateurl="~/default.aspx">Home</asp:hyperlink> | </td> <td class="OtherTabs"> <asp:hyperlink id="authAbout" runat="server" navigateurl="~/about.aspx">About</asp:hyperlink> | </td> <td class="OtherTabs"> <asp:loginstatus id="authLoginStatus" runat="server"> </asp:loginstatus> </td> </tr> </loggedintemplate></asp:loginview>
將按照顯示的順序分析這些模板,并將第一個匹配的角色用作該登錄控件的內容。這意味著必須仔細地為角色安排適當的順序。我的示例程序的結果是將新的“Admin”(管理)菜單項限制為只對分配了管理角色的用戶顯示。
我們還可以指定 <authorization>
規則拒絕或允許特定的角色,從而實現使用角色來控制對其他資源的訪問??梢允褂?<location>
標記在 web.config 文件的應用程序級別實現這一點,或是將 web.config 文件添加到受保護的子目錄。我在示例程序的 /admin 目錄下放置了以下 <authorization>
設置,只允許那些指定為管理角色的用戶訪問:
<authorization> <allow roles="Admin" /> <deny users="*" /> </authorization>
現在,可以創建一些管理頁面來管理成員,并根據 ASP.NET Whidbey 提供的成員身份 API 來編寫代碼。
至此,我所顯示的大多數內容都是基于使用新的安全控件。但是,有一些基礎組件允許我們直接管理用戶和角色。這些組件提供了從數據庫訪問層抽象而來的層。為了進行演示,我將在 /admin 目錄下創建一個新的內容頁面 (manageMembers.aspx)。該頁面將顯示電子通訊成員的列表,并提供了一個中心界面,用于添加、編輯或刪除電子通訊成員。
我將“DataView”(數據視圖)控件拖放到頁面中,目的是使用用戶列表填充此控件。Page_Load 事件包含了利用內部成員身份對象檢索所有用戶的代碼。新的 Membership 類的方法和屬性提供了對默認創建的成員身份數據庫的直接訪問。例如,GetAllUsers() 返回了應用程序的 MembershipUser 對象的集合。以下代碼將返回的集合轉換為可以綁定到 DataView 控件的格式(用于 Alpha 版本的解決方案,因為該版本中不能綁定集合):
MembershipUserCollection members = Membership.GetAllUsers ();ArrayList arr = new ArrayList ();foreach (MembershipUser member in members){arr.Add (member);}GridView1.DataSource = arr;GridView1.DataBind ();
在該頁面中,用戶可以添加、編輯或從列表刪除成員。刪除鏈接需僅執行以下代碼行:
Membership.Provider.DeleteUser(user);
添加和編輯成員由所創建的另一個新頁面 (newMembers.aspx) 來處理。添加新成員時,該頁面收集要添加到成員數據庫的新成員的必需信息。就我的電子通訊而言,我將收集新成員的電子郵件地址和密碼,僅此而已。但是,數據庫支持一個用戶名和一個電子郵件地址,所以我同時使用電子郵件地址來填充這兩個字段。此外,我將收集新用戶的角色選擇。這意味著我必須編寫代碼,以動態列出應用程序中所有可用的角色。
Page_Load 事件包含用于加載可用角色的代碼。我將使用“Repeater”控件來動態構建一個復選框列表(與安全配置向導中的列表類似)。
// 從 newMember.aspx
<asp:repeater runat="server" id="roleRepeater"> <itemtemplate> <asp:checkbox runat="server" id="chkRole" text='<%# Container.DataItem.ToString()%>' checked="<%# m_theUser == null ? false : Roles.IsUserInRole(m_theUser.Username, Container.DataItem.ToString())%>"/> <br/> </itemtemplate></asp:repeater>// 從 newMember.aspx.cs
roleRepeater.DataSource = Roles.GetAllRoles ();roleRepeater.DataBind ();
所生成的輸入頁面如下所示:
圖 18:您也可以為自己的成員管理進程添加重設密碼、更改密碼和密碼問題及答案功能。
我必須手動設計該頁面,但其中添加新用戶所需的代碼很少,因為可以再次使用成員身份組件:
Membership.CreateUser(email.Text, pw.Text, email.Text);
我們需要多編寫幾行代碼,以從 Repeater 控件中提取角色選擇,然后用該用戶的提取結果填充角色表。同樣,訪問角色數據庫是很容易的,這次使用的是“Roles”(角色)組件:
string[] users = {email.Text};string[] addRoles = new string[roleRepeater.Items.Count];string[] remRoles = new string[roleRepeater.Items.Count];int addIndex = 0;int remIndex = 0;foreach (RepeaterItem itm in roleRepeater.Items){CheckBox c = (CheckBox)itm.FindControl ("chkRole");string role = c.Text;if (c.Checked && !Roles.IsUserInRole(users[0], role)
) addRoles[addIndex++]=role;else if (!c.Checked &&Roles.IsUserInRole(users[0], role)
) remRoles[remIndex++]=role;}if (addIndex > 0){string [] theRoles = new string[addIndex]; Array.Copy (addRoles, 0, theRoles, 0, addIndex);Roles.Provider.AddUsersToRoles (users, theRoles)
;}if (remIndex > 0){string [] theRoles = new string[remIndex]; Array.Copy (remRoles, 0, theRoles, 0, remIndex);Roles.Provider.RemoveUsersFromRoles (users, theRoles)
;}
同一 newMembers.aspx 頁面可以用于編輯用戶,查詢字符串則用于指示當前的模式。在編輯模式中,Page_Load 將使用用戶信息和當前角色填充界面。同樣,Membership 類提供了查找特定用戶記錄和更新已更改用戶記錄的方法。如果我使用純文本密碼,并且在成員身份提供程序配置設置中啟用了密碼檢索,那么以下代碼將更新用戶的密碼更改:
MembershipUser user = Membership.GetUser (email.Text); user.ChangePassword (user.GetPassword (), this.pw.Text);
默認情況下,GetPassword() 將失敗,因為對所添加的安全性安裝了每個成員身份提供程序的 machine.config 設置。此外,散列密碼是提供程序的默認、也是推薦的方式。因為散列密碼不可檢索,所以您將必須從用戶界面收集用戶的舊密碼,以調用 ChangePassword() 函數。
至此,我一直側重于如何才能更輕松地實現驗證和基于角色的訪問控制。雖然這些已封裝的功能可以滿足您百分之八十的需求,您還可以非常容易地擴展該模型。
例如,可以直接通過安全配置向導將數據庫創建過程擴展為支持 SQL Server 數據庫,或是另一個自定義的 Access 數據庫。如果在向導的步驟中選擇創建一個新數據庫,您將看到如下的示例圖:
圖 19:安全向導將在您所選擇的本地或遠程數據庫中創建默認的一組成員身份管理表。
您可以在應用程序的 SQL Server 數據庫中直接創建成員身份表,而不是使用無法進行任何擴展的 Access 數據庫。這是我認為有進步的地方。也許您的祖母無法知道完成該步驟所需的數據庫名稱和憑據,但您的開發小組肯定知道。系統將封裝所創建的表,以匹配成員身份和角色提供程序(這兩者用于實現上述功能)的需要。但如果計劃編譯自己的提供程序,您可以使用其他表設計,并跳過這一步。
您可能從我們編寫的、用于構建某些管理功能的代碼中發現,對憑據存儲的訪問由成員身份和角色提供程序進行處理。System.Web.Security 命名空間現在包括新的 SqlMembershipProvider 和 AccessMembershipProvider 組件,以管理各自對默認憑據表的數據訪問需求。默認情況下,machine.config 文件的 <membership>
元素包括兩個提供程序,分別用于 SQL Server 數據庫和 Access 數據庫。<providers>
節可用于添加或刪除提供程序,這允許您在應用程序級別刪除這些默認的提供程序,并配置自己的提供程序。從以下設置中可以看到,有一些與向導創建的表結構直接相關的預定義設置,包括密碼加密設置、密碼重設和檢索設置、密碼問題及答案的要求設置,以及電子郵件字段輸入內容的唯一性設置。其中的每一項都由各自的默認成員身份(或數據庫)提供程序來強制執行,這使您可以使用多種方法使用已封裝的表結構,而不是通過創建自己的表和提供程序。您也可以替代各個提供程序所用的連接字符串。
<membership defaultProvider="AspNetAccessProvider" userIsOnlineTimeWindow="15" > <providers> <add name="AspNetSqlProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=1.2.3400.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="LocalSqlServer" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" applicationName="/" requiresUniqueEmail="false" passwordFormat="Hashed" description="從本地 Microsoft SQL Server 數據庫中存儲和檢索成員身份數據" /> <add name="AspNetAccessProvider" type="System.Web.Security.AccessMembershipProvider, System.Web, Version=1.2.3400.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="AccessFileName" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" applicationName="/" requiresUniqueEmail="false" passwordFormat="Hashed" description="從本地 Microsoft Access 數據庫中存儲和檢索成員身份數據" /> </providers> </membership>
實際上,還有另一個成員身份提供程序組件 System.Web.Security.ADMembershipProvider。該組件對 Active Directory 存儲執行上述同樣的活動,但目前這只是內部功能。
<roleManager>
節中的配置設置可以控制使用何種數據存儲來訪問相關的角色信息。默認情況下有三種配置設置:SqlRoleProvider、AccessRoleProvider 和 WindowsTokenRoleProvider。這些組件用于處理用戶所有的角色管理。同樣,將為 SQL Server 數據庫和 Access 數據庫創建一組默認表,WindowsTokenRoleProvider 調用未托管的代碼來訪問為操作系統憑據存儲而定義的角色。
<roleManager enabled="false" cacheRolesInCookie="true" cookieName=".ASPXROLES" cookieTimeout="30" cookiePath="/" cookieRequireSSL="false" cookieSlidingExpiration="true" cookieProtection="All" defaultProvider="AspNetAccessProvider" > <providers> <add name="AspNetSqlProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=1.2.3400.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="LocalSqlServer" applicationName="/" description="從本地 Microsoft SQL Server 數據庫中存儲和檢索角色數據" /> <add name="WindowsToken" type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=1.2.3400.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" description="從請求的 Windows 已驗證令牌檢索角色數據" /> <add name="AspNetAccessProvider" type="System.Web.Security.AccessRoleProvider, System.Web, Version=1.2.3400.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="AccessFileName" applicationName="/" description="從本地 Microsoft Access 數據庫文件中存儲和檢索角色數據" /> </providers> </roleManager>
雖然此提供程序模型主要旨在簡化 Web 應用程序的表單驗證,但也可用于創建并管理用戶和角色的任意驗證方案,還可執行通用活動,如密碼重設、密碼加密和用戶驗證。
ASP.NET Whidbey 中的新組件和體系結構功能令人贊嘆不已。新功能真正讓人欣賞之處在于,您可以輕易地把各種功能組合在一起,構建成一個完整的應用程序,此外,對于需要具有可伸縮性的企業級應用程序,您可以非常容易地擴展這些功能。安全性也有了顯著的加強。使用新模型使我們可以和使用 XML 配置文件開發可憐的“演示代碼”說再見(這些 XML 配置文件保存未加密的憑據,并增加了服務器的文件訪問負載)。當截至日期臨近時,我們經常冒險發行演示代碼。為什么不在第一次就開發出正確的代碼呢?現在唯一欠缺的是心靈感應設備驅動程序,可以將我的想法實時轉換成代碼。
新聞熱點
疑難解答