2016-10-28 58 views
4

我正在处理asp.net mvc 5.我想要将控制器的动作方法的权限动态分配给角色,而无需在Authorize属性中硬性地赋予角色。动态地为asp.net MVC中的角色分配控制器操作权限

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

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

在这里,我想使用户界面如下 -

Role Management UI

任何人都可以请帮我做这件事给予任何建议或代码或链接?

+0

您是否已经在项目中使用角色? – SeM

+0

这里我从AspNetRole表中检索了角色。我种下这个桌子有四个角色。但我担心的是,我可以如何让管理员将操作方法​​的权限从UI分配给角色。此用户界面用于演示目的。我想要像这样创建。 –

+0

我已经问过这个问题,知道您是使用分配角色还是使用否的部分,所以如果是的话,当您检查/取消选中复选框时,您只需要使用该部分。 – SeM

回答

1

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

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

4

想象一下,你有服务基于控制器和动作名称这样它返回角色的数组:

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); 
    } 
} 

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

[DynamicRoleAuthorize] 
public ActionResult MyAction() 
{ 

} 
+0

嗨,你可以编辑或修改这个如何从性能的方式从一个Db或配置文件获取角色,所以我们可以'角色= string.Join(“,”,_rolesProvider.Get(controller,action));'这将是一个很大的帮助。因为,当我在代码中尝试这个时,它在编译期间抱怨! – transformer

+0

角色映射在哪里进行处理,即在何处配置,重新保存和检查?另外,这可以处理运行时,还是需要重新启动应用程序?在你的解决方案中请澄清我感兴趣 – transformer

+1

@transformer'roleProvider'是一个假想的类,它负责根据控制器和操作获取相关角色。你可以自己写。想象一下,你在数据库中有一个表格,并为每个控制器分配角色,然后通过这个类别获取指定的角色。每次调用某个操作时都会处理角色映射,因此如果您分配了新角色,则无需重新启动应用程序。 –

1

虽然这不会给你所需的动态网页分配,但如果你的方法很灵活......你可以设置一个Enum list of Roles Admin, Editor editor etc,并将它们作为参数对象(ENUM)作为参数传递,所以该DynamicRoleAuthorize可以使用它加载所允许

vivians blog构造函数接受的对象类型的参数的作用,即小动作。如果使用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))); 
    } 
    } 
}