【问题标题】:MvcSiteMapProvider not picking up roles for menuMvcSiteMapProvider 没有为菜单选择角色
【发布时间】:2016-07-19 04:49:48
【问题描述】:

我正在使用 MVC5、Windows 身份验证、结构映射 DI 和自定义角色提供程序。

MVC5 的 MvcSiteMapProvider 没有根据用户角色选择角色来显示菜单。启用安全修整后,它仅显示未定义任何角色属性的菜单项。

我在控制器上实现了 ActionFilterAttribute 并用于授权。控制器根据角色正确地将用户重定向到未经授权的页面,但菜单没有选择角色属性来隐藏菜单。

Custom RoleProvider 实现了 GetRolesForUser 和 GetUsersInRole。

任何建议都会有所帮助。

还想知道在 SiteMapNodeModel 中何处查找角色属性。我正在考虑在构建菜单时自定义以在 HtmlHelper 中查找权限。

注意:相同的实现在 MVC4 中运行良好。一旦升级到 MVC5,它就不起作用了。

谢谢

【问题讨论】:

标签: asp.net-mvc-5 roles mvcsitemapprovider


【解决方案1】:

MVC5 的 MvcSiteMapProvider 没有根据用户角色选择角色来显示菜单。启用安全修剪后,它仅显示未定义任何角色属性的菜单项。

根据the documentation,角色属性不适用于 MVC。它用于与 ASP.NET 页面的互操作。

它仅在安全框架像 Membership 和 Identity 一样实现 IPrincipalIIdentity 时起作用。

我在控制器上实现了 ActionFilterAttribute 并用于授权。控制器根据角色正确地将用户重定向到未经授权的页面,但菜单没有选择角色属性来隐藏菜单。

这很可能是您的问题。安全修整只查找AuthorizeAttributeAuthorizeAttribute 的子类。如果您有子类ActionFilterAttribute,它将不会用于隐藏导航中的链接。

当然,要使标准 AuthorizeAttribute 工作,您需要实现 IPrincipalIIdentity 或使用具有相同功能的预构建安全框架之一。

或者,如果您有完全自定义的安全性,您可以构建自己的 IAclModuleISiteMapNodeVisibilityProvider

还想知道在 SiteMapNodeModel 中何处查找角色属性。我正在考虑在构建菜单时自定义以在 HtmlHelper 中查找权限。

您无需从SiteMapNodeModel 中查找角色。相反,您应该从当前上下文中获取角色,并相应地更改 /Views/Shared/DisplayTemplates/ 中的菜单模板。

如果您使用的框架支持IPrincipalIIdentity,则可以使用:

@if (User.IsInRole("SomeRole"))
{
    ...
}

另请参阅以下内容:

如果要获取为操作方法配置的当前角色,可以构建扩展方法以从当前AuthorizeAttribute 中读取角色。同样,roles 属性仅用于与 ASP.NET 的互操作性,不应用于纯 MVC,因为这意味着您无论如何都需要在AuthorizeAttribute 上复制您的角色。

public static class ControllerContextExtensions
{
    public static IEnumerable<string> Roles(this ControllerContext controllerContext)
    {
        var controllerType = controllerContext.Controller.GetType();
        var controllerDescriptor = new ReflectedControllerDescriptor(controllerType);
        var actionName = controllerContext.RouteData.Values["action"] as string;
        var actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);

        var authorizeAttribute = FilterProviders.Providers.GetFilters(controllerContext, actionDescriptor)
            .Where(f => typeof(AuthorizeAttribute).IsAssignableFrom(f.Instance.GetType()))
            .Select(f => f.Instance as AuthorizeAttribute).FirstOrDefault();

        string[] roles = { };
        if (authorizeAttribute != null && authorizeAttribute.Roles.Length > 0)
        {
            roles = Array.ConvertAll(authorizeAttribute.Roles.Split(','), r => r.Trim());
        }

        return roles;
    }
}

用法

在视图中:

{ var roles = this.ViewContext.Controller.ControllerContext.Roles(); }

在控制器中:

var roles = this.ControllerContext.Roles();

SiteMapNodeModel获取角色:

    var siteMap = MvcSiteMapProvider.SiteMaps.Current;
    var siteMapNode = siteMap.FindSiteMapNodeFromKey(SiteMapNodeModel.Key);
    var roles = siteMapNode.Roles;

【讨论】:

  • 我正在考虑在创建菜单时检查角色。我想知道如何从 Mvc.sitemap xml 中获取角色信息。我正在循环 SitemapNodeModel 列表以创建菜单,但我在任何地方都看不到 roies。如果我将 xml 中的角色重命名为其他名称,我可以在创建菜单时在节点的属性属性中看到它。我希望以某种方式获得在 xml 中定义的角色列表。我在获取用户权限时没有问题..
  • 谢谢。阅读角色的好方法。我不是在询问用户角色。我在询问 Mvc.sitemap xml 中定义的角色。我正在创建如下菜单
  • 谢谢。非常有帮助。会尝试
猜你喜欢
  • 2022-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多