【问题标题】:Building an ASP.NET MVC Master Page Menu Dynamically, Based on the current User's "Role"基于当前用户的“角色”动态构建 ASP.NET MVC 母版页菜单
【发布时间】:2010-02-04 21:23:18
【问题描述】:

我见过一些类似的问题,但没有一个看起来像我正在尝试做的。

这是我当前的实现,没有任何安全性:

<div id="menucontainer">
    <ul id="menu">              
        <li><%= Html.ActionLink("Main List", "Index", "AController")%></li>
        <li><%= Html.ActionLink("Product List", "Index", "BController")%></li>
        <li><%= Html.ActionLink("Company List", "Index", "CController")%></li>
        <li><%= Html.ActionLink("User List", "Index", "DController")%></li>
    </ul>
</div>

这很好,上面的工作。我在 CController 和 DController 的操作上设置了 [Authorize] 属性,以防止未经授权的访问——但我想为没有正确角色的用户从菜单中删除这些项目,因为当他们看到并单击在它上面,它告诉他们他们没有权限,他们会想要它。如果他们不知道它的存在,那对所有相关人员来说都会更好......

这样的事情最终是我想要达到的目标,但我正在寻找更多 MVC 风格的方法,其中“视图”是“愚蠢的”:

<div id="menucontainer">
    <ul id="menu">              
        <li><%= Html.ActionLink("Main List", "Index", "AController")%></li>
        <li><%= Html.ActionLink("Product List", "Index", "BController")%></li>
        <% If(Role = Roles.Admin) { %>
        <li><%= Html.ActionLink("Company List", "Index", "CController")%></li>
        <li><%= Html.ActionLink("User List", "Index", "DController")%></li>
        <% } %>
    </ul>
</div>

【问题讨论】:

  • 我是……我想。有两个级别的用户,普通和管理员。只有管​​理员可以看到公司和用户列表,控制器上的 [Authorize] 属性可以防止未经授权的访问,但我想对非管理员隐藏视图,这样他们甚至都不知道它在他们的脑海中。跨度>

标签: c# .net asp.net asp.net-mvc security


【解决方案1】:

我做过这样的事情:

  • 为我的控制器使用公共基类(“层超类型”)
  • 在 BaseController 中,覆盖 OnActionExecuted(您也可以为此定义一个 ActionFilter 属性)

类似这样的:

    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        // build list of menu items based on user's permissions, and add it to ViewData
        IEnumerable<MenuItem> menu = BuildMenu(); 
        ViewData["Menu"] = menu;
    }

在母版页中:

    <% var model = ViewData["Menu"] as IEnumerable<MenuItem>; %>
    <% Html.RenderPartial("Menu", model); %>

(注意:实际上,我有一个 MasterViewModel,其中包含菜单模型)

【讨论】:

  • 我认为 ActionExecutedContext 会有关于当前用户的信息?我只需要更新我的所有控制器以从我定义的这个新的基本控制器继承?
  • 是的,ActionExecutedContext 让您可以访问 a.o. HttpContext
  • 嘿,我觉得自己像个完全的 n00b,但这对我来说是新的。谢谢。
  • @jeroenh:所以我在这里开始了另一个线程来引用您的答案。基本上,我试图充实你对全班的回答,但我正在努力把它做好。不知道你是否想投入你的 2 美分。 stackoverflow.com/questions/2999918/…
【解决方案2】:

您听说过 MvcContrib 的 MenuBuilder 吗?

如果没有,我建议你看看它。示例项目UI 是开始学习如何使用它的好方法。

【讨论】:

    【解决方案3】:

    没有人提到 MvcSiteMapProvider 这样做并且可以使用 NuGet 轻松集成到您的 Visual Studio 项目中。

    【讨论】:

      【解决方案4】:

      通常我只是以与您类似的方式检查角色,然后使用链接呈现部分视图或创建它们。像这样使用 Razor 语法的东西。我使用 T4MVC 进行操作。

      @if(User.IsInRole("Admin"))
      {
          <li><a href="@Url.Action(MVC.Admin.User.Index())">Users</a></li>
      }
      

      为了安全,我使用 Fluent Security。 希望这可以帮助。

      【讨论】:

        【解决方案5】:

        就像@SD 所说的那样,您可以创建一个“闪亮”的助手,根据您的安全要求,它可以渲染或不渲染链接。

        这是关于自定义助手的好读物(朝向底部):

        understanding-html-helpers on S. Walther's blog

        【讨论】:

          【解决方案6】:

          到目前为止,Joe 的解决方案是最简单的,并且对我有用。我的页面存在于不同的区域,我需要快速设置一个菜单系统,该系统根据用户所在的区域做出反应和工作。同样在我的情况下,我的系统中没有跨区域链接,所以我要下一个configure multiple sitemaps for the MvcSiteMapProvider

          希望这可以帮助其他寻找简单有效解决方案的人!

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-03-19
            • 2018-11-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-06-11
            • 1970-01-01
            • 2014-03-19
            相关资源
            最近更新 更多