MVCSiteMap节点Requring多重角色 [英] MVCSiteMap Node Requring Multiple Roles

查看:424
本文介绍了MVCSiteMap节点Requring多重角色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经设置了使用MVCSiteMap我的菜单,我有这样的节点:

I've set up my menu using MVCSiteMap and I have this node:

<mvcSiteMapNode title="Courses Form" controller="Booking" action="Course" roles="CORLIC, VIEWCOBO"/>

我试图强制执行此节点必须有角色CORLICANDVIEWCOBO它是可见的,但当然这意味着它将如果用户具有上述的显示。

I'm trying to enforce that this node must have roles "CORLIC" AND "VIEWCOBO" for it to be visible but of course this means that it will be displayed if the user has either of the above.

这可能吗?

感谢。

推荐答案

角色属性是与ASP.NET的互操作性,不应在一个MVC-唯一的应用程序中使用。

The roles attribute is for interoperability with ASP.NET and should not be used in an MVC-only application.

有关MVC,如果你已经在你的控制器动作定义AuthorizeAttribute,MvcSiteMapProvider会自动接他们,并相应地隐藏匹配的节点,如果的安全修整已启用。

For MVC, if you are already defining the AuthorizeAttribute on your controller actions, MvcSiteMapProvider will automatically pick them up and hide the matching nodes accordingly if security trimming is enabled.

[Authorize]
public ActionResult Course()
{
    return View();
}

[Authorize]
[HttpPost]
public ActionResult Course(CourseModel model)
{
    if (ModelState.IsValid)
    {
        // Implementation omitted
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

默认<一个href=\"https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Http/AuthorizeAttribute.cs\"相对=nofollow> AuthorizeAttribute 接受角色,但它以同样的方式工作的角色属性 - 也就是说,该用户是在将导致它成功的任何角色

The default AuthorizeAttribute accepts roles, but it works in the same way as the roles attribute - that is, any role that the user is in will cause it to succeed.

不过,你可以自己继承AuthorizeAttribute和重写<一​​个href=\"https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Http/AuthorizeAttribute.cs#L84\"相对=nofollow> IsAuthorized方法需要改变的逻辑。

However, you could inherit AuthorizeAttribute yourself and override the IsAuthorized method to change the logic as needed.

public class SpecialAuthorizeAttribute : AuthorizeAttribute
{
    private string _requiredRoles;
    private string[] _requiredRolesSplit = new string[0];

    /// <summary>
    /// Gets or sets the required roles. The user must be a member of all roles for it to succeed.
    /// </summary>
    /// <value>
    /// The roles string.
    /// </value>
    /// <remarks>Multiple role names can be specified using the comma character as a separator.</remarks>
    public string RequiredRoles
    {
        get { return _requiredRoles ?? String.Empty; }
        set
        {
            _requiredRoles = value;
            _requiredRolesSplit = SplitString(value);
        }
    }

    /// <summary>
    /// Determines whether access for this particular request is authorized. This method uses the user <see cref="IPrincipal"/>
    /// returned via <see cref="HttpRequestContext.Principal"/>. Authorization is denied if the user is not authenticated,
    /// the user is not in the authorized group of <see cref="Users"/> (if defined), or if the user is not in any of the authorized 
    /// <see cref="Roles"/> (if defined).
    /// </summary>
    /// <param name="actionContext">The context.</param>
    /// <returns><c>true</c> if access is authorized; otherwise <c>false</c>.</returns>
    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        if (actionContext == null)
        {
            throw new ArgumentNullException("actionContext");
        }

        IPrincipal user = actionContext.ControllerContext.RequestContext.Principal;
        if (user == null || user.Identity == null || !user.Identity.IsAuthenticated)
        {
            return false;
        }

        // Ensure all of the roles in RequiredRoles are present.
        if (_requiredRolesSplit.Length > 0 && !_requiredRolesSplit.All(user.IsInRole))
        {
            return false;
        }

        // Call the base class to check the users and roles there.
        return base.IsAuthorized(actionContext);
    }

    /// <summary>
    /// Splits the string on commas and removes any leading/trailing whitespace from each result item.
    /// </summary>
    /// <param name="original">The input string.</param>
    /// <returns>An array of strings parsed from the input <paramref name="original"/> string.</returns>
    internal static string[] SplitString(string original)
    {
        if (String.IsNullOrEmpty(original))
        {
            return new string[0];
        }

        var split = from piece in original.Split(',')
                    let trimmed = piece.Trim()
                    where !String.IsNullOrEmpty(trimmed)
                    select trimmed;
        return split.ToArray();
    }
}

然后,你可以指定使用新的财产需要哪些角色。

Then you can specify which roles are required by using the new property.

[SpecialAuthorize(RequiredRoles = "CORLIC, VIEWCOBO")]
public ActionResult Course()
{
    return View();
}

[SpecialAuthorize(RequiredRoles = "CORLIC, VIEWCOBO")]
[HttpPost]
public ActionResult Course(CourseModel model)
{
    if (ModelState.IsValid)
    {
        // Implementation omitted
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

另一个可能的选择是使用 FluentSecurity 作为的此处所示。对于FluentSecurity V2.0与MvcSiteMapProvider工作,你需要复制<一个href=\"https://github.com/kristofferahl/FluentSecurity/blob/master/FluentSecurity/HandleSecurityAttribute.cs\"相对=nofollow> HandleSecurityAttribute code 到您的项目,并改变它从AuthorizeAttribute而不是属性继承,然后用它作为FluentSecrity文档中指定。

Another possible option is to use FluentSecurity as shown here. For FluentSecurity v2.0 to work with MvcSiteMapProvider, you need to copy the HandleSecurityAttribute code into your project and change it to inherit from AuthorizeAttribute instead of Attribute, then use it as specified in the FluentSecrity documentation.

这篇关于MVCSiteMap节点Requring多重角色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆