MvcSiteMapProvider 没有为菜单选择角色
MvcSiteMapProvider not picking up roles for menu
我正在使用 MVC5、windows 身份验证、结构图 DI 和自定义角色提供程序。
MVC5 的 MvcSiteMapProvider 没有选择角色来根据用户角色显示菜单。启用安全修整后,它仅显示未定义任何角色属性的菜单项。
我在控制器上实现并使用了 ActionFilterAttribute 进行授权。控制器根据角色正确地将用户重定向到未经授权的页面,但菜单未选择角色属性来隐藏菜单。
自定义 RoleProvider 具有 GetRolesForUser 和 GetUsersInRole 的实现。
任何建议都会有所帮助。
还想知道在 SiteMapNodeModel 中的何处查找角色属性。我正在考虑自定义以在构建菜单时在 HtmlHelper 中寻找权限。
注意:相同的实现在 MVC4 中运行良好。一旦升级到 MVC5,它就不起作用了。
谢谢
MvcSiteMapProvider for MVC5 is not picking up the roles to show menu based on user role. When security trimming is enabled it shows only menu items which do not have any roles attribute defined.
根据 the documentation,角色属性不适用于 MVC。它用于与 ASP.NET 个页面互操作。
它仅在安全框架像成员身份和身份一样实现 IPrincipal
和 IIdentity
时起作用。
I have ActionFilterAttribute implemented and used on controller for authorization. Controller correctly redirects the user to unauthorized page based on roles but menu is not picking the role attributes to hide the menu.
这很可能是您遇到的问题。安全修整仅查找 AuthorizeAttribute
和 AuthorizeAttribute
的子类。如果您有子类化 ActionFilterAttribute
,它将不会用于隐藏导航中的链接。
当然,要使标准 AuthorizeAttribute
正常工作,您需要实施 IPrincipal
和 IIdentity
或使用具有相同功能的预构建安全框架之一。
或者,如果您拥有完全自定义的安全性,您可以构建自己的 IAclModule
或 ISiteMapNodeVisibilityProvider
。
Also want to know where to look for roles attributes in SiteMapNodeModel. I am thinking of customizing to look for permission in the HtmlHelper while building the menu.
您不需要从 SiteMapNodeModel
中寻找角色。相反,您应该从当前上下文中获取角色,并相应地对 /Views/Shared/DisplayTemplates/
中的菜单模板进行更改。
如果您使用的框架支持 IPrincipal
和 IIdentity
,您可以只使用:
@if (User.IsInRole("SomeRole"))
{
...
}
另请参阅以下内容:
- ASP.NET MVC 5 Customise Bootstrap navbar based on User Role
- Implementing Role Based Menu in ASP.NET MVC 4
如果要获取为操作方法配置的当前角色,可以构建扩展方法以从当前 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;
我正在使用 MVC5、windows 身份验证、结构图 DI 和自定义角色提供程序。
MVC5 的 MvcSiteMapProvider 没有选择角色来根据用户角色显示菜单。启用安全修整后,它仅显示未定义任何角色属性的菜单项。
我在控制器上实现并使用了 ActionFilterAttribute 进行授权。控制器根据角色正确地将用户重定向到未经授权的页面,但菜单未选择角色属性来隐藏菜单。
自定义 RoleProvider 具有 GetRolesForUser 和 GetUsersInRole 的实现。
任何建议都会有所帮助。
还想知道在 SiteMapNodeModel 中的何处查找角色属性。我正在考虑自定义以在构建菜单时在 HtmlHelper 中寻找权限。
注意:相同的实现在 MVC4 中运行良好。一旦升级到 MVC5,它就不起作用了。
谢谢
MvcSiteMapProvider for MVC5 is not picking up the roles to show menu based on user role. When security trimming is enabled it shows only menu items which do not have any roles attribute defined.
根据 the documentation,角色属性不适用于 MVC。它用于与 ASP.NET 个页面互操作。
它仅在安全框架像成员身份和身份一样实现 IPrincipal
和 IIdentity
时起作用。
I have ActionFilterAttribute implemented and used on controller for authorization. Controller correctly redirects the user to unauthorized page based on roles but menu is not picking the role attributes to hide the menu.
这很可能是您遇到的问题。安全修整仅查找 AuthorizeAttribute
和 AuthorizeAttribute
的子类。如果您有子类化 ActionFilterAttribute
,它将不会用于隐藏导航中的链接。
当然,要使标准 AuthorizeAttribute
正常工作,您需要实施 IPrincipal
和 IIdentity
或使用具有相同功能的预构建安全框架之一。
或者,如果您拥有完全自定义的安全性,您可以构建自己的 IAclModule
或 ISiteMapNodeVisibilityProvider
。
Also want to know where to look for roles attributes in SiteMapNodeModel. I am thinking of customizing to look for permission in the HtmlHelper while building the menu.
您不需要从 SiteMapNodeModel
中寻找角色。相反,您应该从当前上下文中获取角色,并相应地对 /Views/Shared/DisplayTemplates/
中的菜单模板进行更改。
如果您使用的框架支持 IPrincipal
和 IIdentity
,您可以只使用:
@if (User.IsInRole("SomeRole"))
{
...
}
另请参阅以下内容:
- ASP.NET MVC 5 Customise Bootstrap navbar based on User Role
- Implementing Role Based Menu in ASP.NET MVC 4
如果要获取为操作方法配置的当前角色,可以构建扩展方法以从当前 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;