拒绝具有管理员角色的用户编辑具有管理员角色的用户Asp.Net MVC5身份

时间:2016-08-10 15:47:31

标签: asp.net-mvc entity-framework-6 authorization asp.net-identity asp.net-roles

我已将应用设置为允许每个用户拥有多个角色。

public class SelectRoleViewModel
{      
    public string Id { get; set; }
    public bool Checked { get; set; }        
    public string RoleName { get; set; }
    public string Description { get; set; }
}

public class EditUser
{
   // other properties

  public List<SelectRoleViewModel> Roles { get; set; }
}

现在在Controlles中,在Edit get方法中我写了这个

[CustomAuthorize(Roles = ("Admin,Manager"))]
    public ActionResult Edit(string Id)
    {
        var editUser = GetEditUser(Id);

        bool isAdmin = User.IsInRole("Admin");

        if (!isAdmin)
        {      
            if (editUser.Roles.Exists(x => x.RoleName == "Admin"))
            {
                return RedirectToAction("AccessNotAllowed", "Errors");
            }
        }

        // Here just edit what you want
        return View(editUser);                        
    }

private EditUser GetEditUser(string Id)
    {
        var dbUser = UserManager.Users.Where(x => x.Id == Id).FirstOrDefault();
        var currentRoles = dbUser.Roles.Select(x => x.RoleId).ToList();
        var allRoles = _roleManager.Roles.ToList();

        EditUser editUser = new EditUser();
        foreach (var x in allRoles)
        {
            if (currentRoles.Contains(x.Id))
                editUser.Roles.Add(new SelectRoleViewModel { Id = x.Id, RoleName = x.Name, Description = x.Description, Checked = true });
            else
                editUser.Roles.Add(new SelectRoleViewModel { Id = x.Id, RoleName = x.Name, Description = x.Description, Checked = false });
        }

        if (User.IsInRole("Manager"))
        {
            // don't show the admin role to set for users if authenticated user is manager
            var adm = editUser.Roles
                        .Where(x => x.RoleName.Equals("Admin", StringComparison.OrdinalIgnoreCase))
                        .FirstOrDefault();
            if (adm != null)
            {
                editUser.Roles.Remove(adm);
            }
        }

        editUser.FirstName = dbUser.FirstName;
        editUser.LastName = dbUser.LastName;
        editUser.Email = dbUser.Email;
        editUser.UserName = dbUser.UserName;
        editUser.Id = dbUser.Id;
        return editUser;
    }

因此,经理有权编辑用户并创建用户,但经理无法创建具有管理员角色的用户。 我要做的是拒绝管理员编辑管理员用户的权限。 我编写的代码,它占用了整个用户角色列表,并且由于存在管理员角色,因此它始终拒绝编辑用户的访问权限。 当我在GetEditUser方法中注释掉这段代码时会发生这种情况:

if (User.IsInRole("Manager"))
        {
            // don't show the admin role to set for users if authenticated user is manager
            var adm = editUser.Roles
                        .Where(x => x.RoleName.Equals("Admin", StringComparison.OrdinalIgnoreCase))
                        .FirstOrDefault();
            if (adm != null)
            {
                editUser.Roles.Remove(adm);
            }
        }

并使用此代码(取消注释),它完全从列表中删除管理员角色,因此管理员仍然可以编辑管理员用户,因为它在if条件中找不到要比较的管理员角色。

有人可以帮我找到一个解决方案来限制管理员访问权限,以便在创建新用户时隐藏管理员的管理员角色,而无需更改用户只分配1个角色吗?应用程序的逻辑需要为每个用户提供多个角色。

1 个答案:

答案 0 :(得分:2)

将指示的代码段移动到if(!isAdmin)中的Edit方法:

    if (!isAdmin)
    {      
        if (editUser.Roles.Exists(x => x.RoleName == "Admin" && x.Checked))
        {
            return RedirectToAction("AccessNotAllowed", "Errors");
        }
        var adm = editUser.Roles
                    .Where(x => x.RoleName.Equals("Admin", StringComparison.OrdinalIgnoreCase))
                    .FirstOrDefault();
        if (adm != null)
        {
            editUser.Roles.Remove(adm);
        }
    }