原文地址:http://aspnet.4guysfromrolla.com/articles/053007-1.aspx
[原文源碼下載]
[翻譯]開發自己的web網站管理工具(Website Administration Tool)(2)
原文發布日期:2007.05.30
作者:Dan Clem
翻譯:webabcd
介紹
為了方便系統管理使用者、角色和使用權限設定,ASP.NET 2.0內建了Web Site Administration Tool (WSAT),你可以在Visual Studio 2005的“網站”菜單下選擇“ASP.NET 配置”來啟動WSAT。 但是,WSAT只允許你管理本地的web網站。 當web網站部署在遠程web主機上的時候,WSAT就會受到一些限制。 所以,我決定從零開始開發一個自己的WSAT程式。本系列文章的第一部分從整體上講述了我的自訂WSAT程式的實現,並且講解了其中關於使用者管理的部分。
本文是該系列文章的第二部分,也是最後一部分,在這裡我會詳細講解上一篇文章中沒有說明的一些要點: 角色管理和訪問規則管理。 你可以在本文的結尾處下載我寫的WSAT程式的全部代碼。 關於如何在一個建立或已有的web程式中使用我的這個WSAT程式,你可以參考本系列文章的第一部分(譯者註:中文在這裡)中的“使用我的自訂web網站管理工具(WSAT)”。 繼續往下看,你會學到更多的在我的自訂WSAT程式中關於角色管理和訪問規則管理的相關知識。
你最好已經看過本系列文章的第一部分
在看本文之前,你最好已經閱讀過本系列文章的第一部分(譯者註:中文在這裡)。在第一部分中,我從整體上講述了我的自訂WSAT程式的實現,並且一步一步地說明了如何在一個建立或已有的web程式中使用我的這個WSAT程式,另外,如何?系統管理使用者的功能我也做了充分的講解。 你可以在本文結尾處或本系列文章的第一部分的結尾處下載這個自訂的WSAT程式的全部代碼。
角色管理
我的自訂WSAT程式的角色管理部分完成了如下3個任務:
·顯示系統內的所有角色
·允許刪除一個已存在的角色
·允許建立角色
我把實現這3個任務的功能恰當地放到了一個web頁面內,其截屏如下:
我使用了一個GridView來顯示所有角色。 Roles類的GetAllRoles方法返回的是系統內的角色名稱數組(字串數組)。 除了列出所有角色外,我還想顯示出每一個角色所關聯的使用者的數量。 所以,直接通過GetAllRoles方法返回一個字串數組綁定給GridView滿足不了我的需求,於是我決定構造一個自己的DataTable,並使其作為GridView的資料來源。 我把這段代碼寫到了Page_PreRender方法內。 // 建立一個DataTable,並定義它的列
DataTable RoleList = new DataTable();
RoleList.Columns.Add("Role Name");
RoleList.Columns.Add("User Count");
// 擷取角色列表和每一個角色下的使用者數
string[] allRoles = Roles.GetAllRoles();
foreach (string roleName in allRoles)
{
int numberOfUsersInRole = Roles.GetUsersInRole(roleName).Length;
string[] roleRow = { roleName, numberOfUsersInRole.ToString() };
RoleList.Rows.Add(roleRow);
}
// 綁定DataTable給GridView
UserRoles.DataSource = RoleList;
UserRoles.DataBind();
向系統內添加一個新的角色,只需要下面這樣的一行代碼:Roles.CreateRole(roleName);
同樣,刪除一個角色也只需要一行代碼:Roles.DeleteRole(roleName);
需要注意的是,如果一個角色內有一個或更多的使用者,那麼這時你要刪除這個角色的話,預設的Provider就會拋出一個異常。 所以,在刪除一個角色的時候要先移出角色內的所有成員。你可以調用Roles類的RemoveUsersFromRole方法來做這項工作。 該方法需要兩個參數: 角色內需要移除的成員的使用者名稱數組和角色名稱。 你可以使用GetUsersInRole方法來得到指定角色下的所有使用者(返回的是一個包含使用者名稱稱的字串數組)。
訪問規則管理
在“訪問規則管理”頁中,使用了一個TreeView控制項來顯示web程式內的目錄(檔案夾)結構列表。 樹型結構的顯示是通過Page_Load事件調用的PopulateTree()方法內的代碼實現的。 (我從Scott Mitchell的文章Using the TreeView Control and a DataList to Create an Online Image Gallery中幾乎是一個字一個字地複製了PopulateTree方法和AddNodeAndDescendents方法)
要使用“訪問規則管理”這個功能的話,你需要以隸屬於管理員角色的使用者登入。 在詳細講解之前,我們先來看看.net內建的WSAT程式中總結的一句話: “規則按順序應用。應用合格第一個規則,每個規則中的許可權重寫其後所有規則中的許可權。”
訪問規則的設定儲存在每一個檔案夾中的Web.config檔案內。 你可以手寫這些Web.config檔案,也可以使用WebConfigurationManager類對訪問規則進行管理。 注意一下你的ASP.NET程式是在Windows的哪個使用者之下啟動並執行,一般來說應該是 NT Authority\Network Service使用者,你必須要保證這個使用者有讀寫Web.config檔案的許可權。
在“訪問規則管理”頁中,管理員角色的使用者可以通過單擊左側的分類樹視圖,來管理指定檔案夾的訪問規則。 你可以對訪問規則進行添加、移動或刪除的操作。 子檔案夾的訪問規則會繼承其父資料夾,但是不可以在子檔案夾中更改在父資料夾中制定的訪問規則。 你可以通過指定使用者或角色的Deny和Allow行為來建立新的訪問規則。 我的這個WSAT程式可以設定你所選擇的使用者或角色的許可權, 也可以指定所有使用者(*)或匿名使用者(?)的許可權。
添加規則分兩步走: 首先建立一個規則,然後將其添加到web配置中。 // 建立規則
AuthorizationRule newRule;
if (ActionAllow.Checked) newRule = new AuthorizationRule(AuthorizationRuleAction.Allow);
else
newRule = new AuthorizationRule(AuthorizationRuleAction.Deny);
// 添加規則
if (ApplyRole.Checked && UserRoles.SelectedIndex > 0)
{
newRule.Roles.Add(UserRoles.Text);
AddRule(newRule);
}
else if (ApplyUser.Checked && UserList.SelectedIndex > 0)
{
newRule.Users.Add(UserList.Text);
AddRule(newRule);
}
else if (ApplyAllUsers.Checked)
{
newRule.Users.Add("*");
AddRule(newRule);
}
else if (ApplyAnonUser.Checked)
{
newRule.Users.Add("?");
AddRule(newRule);
}
AddRule方法用於訪問指定檔案夾的設定檔,並添加我們的許可權規則。 private void AddRule(AuthorizationRule newRule)
{
string virtualFolderPath = FolderTree.SelectedValue;
Configuration config = WebConfigurationManager.OpenWebConfiguration(virtualFolderPath);
SystemWebSectionGroup systemWeb = (SystemWebSectionGroup)config.GetSectionGroup("system.web");
AuthorizationSection section = (AuthorizationSection)systemWeb.Sections["authorization"];
section.Rules.Add(newRule);
try
{
config.Save();
RuleCreationError.Visible = false;
}
catch (Exception ex)
{
RuleCreationError.Visible = true;
RuleCreationError.Text = "<div class=\"alert\">An error occurred and the rule was not added.<i>" + ex.Message + "</i></div>";
}
}
向上或向下移動規則需要我們自己來手寫更多的代碼,因為.net沒有提供內建的方法來實現這個功能。 我用的方法是通過一個數組來排序各個規則,從而完成這項工作。 我認為這個方法還是比較簡單的,所以就不詳細說明了,其主要就是先從設定檔中讀出所有規則並放到一個ArrayList對象中,同時再刪除設定檔中的所有規則,然後根據使用者的需要對這個數組進行排序,最後再將排序好的規則重新寫人設定檔中。
“訪問規則摘要”頁的實現方法
讓我們開發我們自已的“訪問規則摘要”頁吧,在.net內建的WSAT程式中是沒有這個功能的。 隸屬於管理員角色的使用者可以在這個頁中查看指定的角色或使用者在各個目錄中的許可權。
在這個頁中,角色和使用者的選擇是通過DropDownList控制項實現的。 當你選擇了一個角色或使用者之後,TreeView控制項就會列出web程式內的所有檔案夾。 它與“訪問規則管理”頁中的TreeView控制項比較相似,所不同的就是這個TreeView控制項用紅色和綠色標記來表示你所選擇的角色或使用者在某目錄中的許可權。 當然就像你認為的那樣,綠色代表你所選擇的角色或使用者有訪問的許可權,紅色則正好相反。 除了紅色和綠色標記之外,TreeView控制項上的文本還會顯示出為什麼你所選擇的角色或使用者會有這樣的許可權。 通過下面的截屏你就可以發現,被選中的使用者為“Franklin Forester”,因為他屬於“Marketing”角色,所以有對marketing檔案夾的存取權限。
讓我們的自訂WSAT程式安全地運行
現在我們就可以把這個自訂WSAT程式移植到我們的建立或已有的web網站裡,為了保證程式的安全,我們希望只有管理員才能訪問它。 為了實現這個功能,需要增加兩個訪問規則。 在我的例子中,我只允許管理員角色有對admin檔案夾的存取權限,然後拒絕其他所有使用者,如所。 注意,允許管理員角色訪問的規則必須在拒絕所有使用者訪問的規則的上面,否則將不會有任何人有許可權訪問這個檔案夾。(如果你不小心使得管理員角色無法訪問admin檔案夾的話, 那麼你就需要手動修改Web.config檔案,以使管理員角色可以訪問你的自訂WSAT程式的admin檔案夾。)
結論
雖然可以通過ASP.NET 2.0內建的web網站管理工具(WSAT)來系統管理使用者、角色和許可權,但是該工具只能在本地使用,而且有一些功能上的不足。 所以本文和本系列文章的第一部分(譯者註:中文在這裡)探討了如何?一個自訂的WSAT程式。 這個自訂WSAT程式可以移植到你的建立或已有的 ASP.NET web程式中,並且可以部署在遠程伺服器。 此外,為了改進原來的WSAT程式,它還附加了一些新的特性。
祝編程愉快!