我正在研究asp.net mvc 5.我想分配控制器的权限'动态角色的动作方法,无需在“授权”属性中强制转换角色。
以下是该方案 - 在我的项目中,我有四个角色 - 学生,教师,项目官员和管理员。 我希望管理员可以随时改变每个角色的可访问性。我不想在控制器的每个操作名称之前使用角色名称对authorize属性进行硬编码,因为管理员将无法更改每个角色的权限。
我想创建一个页面,其中控制器的每个操作方法都将列为复选框,管理员可以选择角色的操作复选框。然后,该角色用户将获得这些操作方法的可访问性。
在这里,我想将UI设为如下 -
任何人都可以通过提供任何建议或代码或链接来帮助我这样做吗?
答案 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)));
}
}
}