基于角色的菜单不起作用,我做错了什么?

时间:2011-08-27 16:55:19

标签: asp.net menu security-trimming

我无法想出这个。

  • 我有以下SiteMap

    <?xml version="1.0" encoding="utf-8" ?>
    
    <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
        <siteMapNode url="~/" title="Root"  description="Go root">
          <siteMapNode url="~/h" title="Home"  description="Go home" />
    
          <siteMapNode url="~/h/uo" title="Ultima Online" description="Ultima Online">        
            <siteMapNode url="~/h/uo/get" roles="RegisteredUser" title="Get account!" description="Get account!" />
          </siteMapNode>
        </siteMapNode>
    </siteMap>
    
    • 我有XmlSiteMapProvider securityTrimmingEnabled="true",指向此站点地图文件。

    • 我要修剪的文件在其文件夹的authorization

      中有一个web.config规则
      <configuration>
        <system.web>
          <authorization>
            <deny users="?" />
          </authorization>
        </system.web>
      </configuration>
      
    • 无法通过网址访问该文件,如果我输入http://localhost/h/uo/get,我会被重定向到登录页面。

    • 我在主页面文件中设置了<asp:Menu>这样的内容:

      <asp:SiteMapDataSource ID="MenuSiteMap" ShowStartingNode="false"
                             SiteMapProvider="MenuSiteMapProvider" runat="server" 
      />
      
      <div>
          <asp:Menu ID="NavigationMenu" runat="server" DataSourceID="MenuSiteMap" 
                    CssClass="menu" EnableViewState="false" 
                    IncludeStyleBlock="false" Orientation="Horizontal"
          />
      </div>
      

然而,当呈现页面时,无论如何,当我甚至没有登录时,我会看到应该被修剪的Get account节点。

  • 我做错了什么?
  • 是否有其他方法可以构建启用安全修整的站点地图导航菜单?

我正在使用ASP.NET 4.0,并使用HttpModule进行URL重写。

1 个答案:

答案 0 :(得分:1)

在阅读http://forums.asp.net/t/975077.aspx/1时,我发现这正是我发生的事情。

如果节点没有URL,则表现良好,但如果确实如此,就像我的所有节点一样。安全修整只是被忽略了。

我通过更直观的基于角色的站点地图实现来解决我的问题,说:

public class TrimmingXmlSiteMapProvider : XmlSiteMapProvider
{
    public override bool IsAccessibleToUser(HttpContext context, SiteMapNode node)
    {
        if (node.Roles.Cast<string>().Any(r => r == "*"))
            return true;

        if (node.Roles.Count > 0 && node.Roles.Cast<string>().Count(Roles.IsUserInRole) == 0)
            return false;

        return node.ParentNode != null && node.ParentNode.IsAccessibleToUser(context);
    }
}

然后,我必须做的唯一改变是在根级别的角色定义中添加一个星号。

这是如何运作的?

首先,我检查为此节点定义的任何角色是否为星号,如果是这种情况,那么我可以看到该节点。

其次,如果节点不是每个人级别,我会检查是否指定了任何角色,以及登录用户是否至少是其中一个。

最后,我检查是否有父节点,并继承他们的规则。

这允许安全修整实际上是“安全修剪”并且不是很好,但是它应该默认工作。