在ASP.NET网站中,是否应为管理员分配多个角色?

时间:2016-06-09 13:43:51

标签: asp.net asp.net-identity membership

此问题确实适用于可为单个用户分配多个角色的任何网站或企业系统。

在ASP.NET Identity中,您有IdentityUserIdentityRole,其中用户可以拥有0个或更多角色。然后,控制器操作受[Authorize(Roles = "roleName")]

保护

给出一个简单的概念系统,它具有以下三个简单的角色:

Administrator
Manager
User

......一个应该有权访问所有控制器操作的简单管理员用户:

JoeAdmin

以下示例Web API控制器:

public IHttpActionResult GetForUsersAndAbove()
{
    //
}

public IHttpActionResult GetForAdminsOnly()
{
    //
}

系统应该设计成:

  1. JoeAdmin只分配一个角色 - 管理员或
  2. JoeAdmin被分配给管理员,经理和用户?
  3. 我要求这样做的动机是授权控制器操作。如果仅为JoeAdmin分配了管理员角色,则基于以下授权属性,他将无法访问GetForUsersAndAbove(),因为他不是用户角色的成员

    [Authorize(Roles = "User")]
    public IHttpActionResult GetForUsersAndAbove()
    ...
    
    [Authorize(Roles = "Administrator")]
    public IHttpActionResult GetForAdminsOnly()
    ...
    

    那么问题是,GetForUsersAndAbove()应该用

    来装饰
    [Authorize(Roles = "User, Manager, Administrator")]
    

    这样他才能访问它?

    系统应该将JoeAdmin分配给所有角色,以便他可以访问所有控制器方法,即使它们标有[Authorize(Roles = "User")]

    修改

    如果我对控制器操作使用以下约定

    [Authorize(Roles = "User")]
    public IHttpActionResult GetForUsers()
    

    并且期望如果JoeAdmin应该访问此方法,他也应该是User角色的成员,这会在假想的用户管理屏幕上引起UI问题:

    这是一个场景:由于负责管理用户,您是系统的新用户。您添加新用户JaneAdmin,意图是她具有对系统的完全/不受限制的访问权限。您会看到3个复选框:AdministratorManagerUser。没有文档来指导你,你勾选哪个复选框?如果我把自己放在那个用户的位置,我会直观地勾选“管理员”,期望它能提供完全访问权限。我还可以想象当JaneAdmin发现她被锁定在简单的用户级操作之外时会感到沮丧。因此,用户界面要求所有3个复选框都应该勾选...这样可以满足系统的授权方面,但却会导致糟糕的用户体验。

    那么人们通常如何处理这个问题呢?

1 个答案:

答案 0 :(得分:1)

你自己回答了自己的问题。为用户提供多个角色更容易,而不是在控制器上指定所有可能的角色,因为角色存储在数据库中并且可以随时操作,但是向控制器添加角色需要重建和重新部署项目。

此外,并非所有管理员都可以访问所有区域。我见过允许管理员创建用户和修改密码的系统,但不允许查看个人医疗记录。

所以是的,我非常建议为用户分配多个角色 - 从长远来看,维护这个角色会更容易。

编辑:您希望超级管理员用户能够在任何地方访问,而无需在所有控制器中明确提及吗?听起来您需要覆盖AuthorizeAttirbute以添加管理员角色以便始终获得授权。

这样的事情:

public class MyAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var authorized = base.AuthorizeCore(httpContext);
        if (!authorized)
        {
            // The user is not authorized => no need to go any further
            return false;
        }


        if(httpContext.User.IsInRole("Admin"))
        {
            return true;
        }

        return base.AuthorizeCore(httpContext);
    }
}

然后用这个新属性装饰你的所有控制器:

[MyAuthorize(Roles = "User")]
public ActionResult MySuperAction()
{
    ...
}