【问题标题】:Using hidden Sitemap nodes to control access使用隐藏的站点地图节点来控制访问
【发布时间】:2014-01-03 02:54:21
【问题描述】:

在我的 Asp.NET C# 应用程序中,我有一个站点地图绑定到用于站点导航的菜单。为了控制用户访问,我使用NHibernate Custom Role Provider by Manuel Abadia,并在每个 SiteMap 节点上设置 Roles 属性。

<siteMapNode title="Add/Modify Roles" description="Add/Modify User Roles"
url="~/MemberPages/Admin_Roles.aspx" roles="Administrator" />

到目前为止一切正常,但现在我希望有几个网页没有出现在站点地图绑定菜单上,但仍使用站点地图节点来控制用户访问。例如,我有一个专供管理员使用的页面,显示数据库中的所有角色 (ViewPage)。在该页面上,我有一个“添加新”按钮,可将用户重定向到另一个页面以添加新角色 (AddPage)。 ViewPage 应该存在于菜单中,而 AddPage 不应该存在,但两者应该共享相同的访问设置(只能由管理员访问)。

我应该如何实现这一目标?我知道我可以在 web.config 文件中声明访问设置,但我宁愿避免这种情况,因为会有很多这样的页面。此外,系统管理员将被允许自定义访问规则,例如将其从仅限管理员更改为管理员和版主,因此如果系统可以更改一个站点地图中所有页面的访问规则会更方便。

【问题讨论】:

  • 我做了类似的事情,向siteMapNode 添加了一个新属性,比如showInMenu="true",它控制节点是否应该出现在菜单中。因此,也许,您的母版页可以读取节点属性以确定节点是否出现在菜单中,以及用户是否有权访问该页面。
  • 附带说明...我添加的另一个属性是forceSSL,用于在某些页面上重定向到 HTTPS。

标签: c# asp.net nhibernate navigation sitemap


【解决方案1】:

感谢MikeSmithDev's comment,我设法找到了一个不错的解决方案。如果其他人遇到同样的问题,这就是我所做的:

在我的站点地图中,我添加了一个自定义属性HideFromMenu:

<siteMapNode title="Add Page" description="Page to Add stuff"
roles="Administrator" url="~/AddPage.aspx" HideFromMenu="true" />

在我的菜单控件中,我添加了OnMenuItemDataBound 属性:

<asp:Menu ID="Menu1" runat="server" DataSourceID="siteMapSource" 
OnMenuItemDataBound="Menu1_MenuItemDataBound" >

在主人的代码隐藏中:

protected void Menu1_MenuItemDataBound(object sender, MenuEventArgs e)
{
    SiteMapNode node = (SiteMapNode)e.Item.DataItem;
    if (node["HideFromMenu"] == "true")
    {
        if (e.Item.Parent != null) //if this item has a parent..
            e.Item.Parent.ChildItems.Remove(e.Item); //use parent to remove child..
        else
            Menu1.Items.Remove(e.Item); //else.. remove from menu itself.
    }
}

最后,为了确保用户不会越界访问页面,我在母版页中添加了一些验证..

var authorizedRoles = SiteMap.CurrentNode.Roles; //obtain the list of authorized roles for the current page

if (authorizedRoles == null || authorizedRoles.Count == 0) // no roles defined for this node
    isAuthorized = false;
else
{
    if (authorizedRoles.Contains("*")) // this page can be accessed by everyone
        isAuthorized = true;

    if (!isAuthorized)
    {
        foreach (string authorizedRoleName in authorizedRoles)
        {
            if (Roles.IsUserInRole(authorizedRoleName) == true)
            {
                isAuthorized = true;
                break;
            }
        }
    }
}

if (!isAuthorized)
    Response.End(); // unauthorised user; kill the page.

我希望这对面临同样问题的人有所帮助。如果有更好的方法可以达到同样的效果,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-22
    • 2017-10-24
    • 1970-01-01
    • 1970-01-01
    • 2015-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多