动态地为asp.net MVC中的角色分配控制器操作权限

时间:2016-10-28 09:29:47

标签: asp.net asp.net-mvc asp.net-identity-2

我正在研究asp.net mvc 5.我想分配控制器的权限'动态角色的动作方法,无需在“授权”属性中强制转换角色。

以下是该方案 - 在我的项目中,我有四个角色 - 学生,教师,项目官员和管理员。 我希望管理员可以随时改变每个角色的可访问性。我不想在控制器的每个操作名称之前使用角色名称对authorize属性进行硬编码,因为管理员将无法更改每个角色的权限。

我想创建一个页面,其中控制器的每个操作方法都将列为复选框,管理员可以选择角色的操作复选框。然后,该角色用户将获得这些操作方法的可访问性。

在这里,我想将UI设为如下 -

Role Management UI

任何人都可以通过提供任何建议或代码或链接来帮助我这样做吗?

3 个答案:

答案 0 :(得分:6)

想象一下,你有一个服务,它根据控制器和动作名称返回角色数组,如下所示:

>>> import numpy
>>> c = numpy.add(a, b).tolist()
>>> c
[[10, 21, 32], [13, 24, 35], [16, 27, 38]]

现在您可以编写自己的授权属性:

public class RoleProvider
{
    public string[] Get(string controller, string action)
    {
        // get your roles based on the controller and the action name 
        // wherever you want such as db
        // I hardcoded for the sake of simplicity 
        return new string[]{"Student", "Teacher"};
    }
}

现在使用您的自定义授权属性,而不是像这样的旧版本:

public class DynamicRoleAuthorizeAttribute: AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var controller = httpContext.Request.RequestContext
            .RouteData.GetRequiredString("controller");
        var action = httpContext.Request.RequestContext
            .RouteData.GetRequiredString("action");
        // feed the roles here
        Roles = string.Join("," ,_rolesProvider.Get(controller, action));
        return base.AuthorizeCore(httpContext);
    }
}

答案 1 :(得分:1)

我认为唯一的方法是实现自己的授权属性,您可以在其中实现自己的授权逻辑。

在您的情况下,您应该有一个关联角色和控制器操作的表,并在您的自定义授权属性中检查此表。

答案 2 :(得分:1)

虽然这不会为您提供您正在寻找的动态网页分配,但如果您的方法灵活...您可以设置Enum list of Roles Admin, Editor editor etc,并将它们作为参数对象传递(ENUM )作为参数,以便DynamicRoleAuthorize可以使用它加载允许的角色

来自vivians blog 构造函数接受object类型的参数,这是一个小技巧。如果您使用Enum类型的参数,您将收到与上面相同的错误消息。我们可以这样做,因为Enum是一个对象。 为了确保我们传递Enum类型的参数,我们检查每个角色的类型。如果一个角色不是Enum类型,则构造函数将抛出ArgumentException。 然后我们使用string.Join方法设置标准Roles属性和我们角色的名称。

using System;
using System.Linq;
using System.Web.Mvc;

namespace MvcApplication.HowTo.Attributes
{
     [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class AuthorizeEnumAttribute : AuthorizeAttribute
{
    public AuthorizeEnumAttribute(params object[] roles)
    {
        if (roles.Any(r => r.GetType().BaseType != typeof(Enum)))
            throw new ArgumentException("roles");

        this.Roles = string.Join(",", roles.Select(r => Enum.GetName(r.GetType(), r)));
    }
   }
}