ASP.NET Identity 2分层角色

时间:2017-06-30 18:10:40

标签: c# asp.net-mvc authorization asp.net-identity

我正在使用Identity 2.0 Framework构建ASP.NET MVC应用程序。我在SQL Server上的AspNet*表上添加了用户和角色。以下是角色的示例:

  • 金融
  • 一般
  • SquadLeader
  • 管理
  • SystemAdmin

SystemAdmin的某个人拥有所有其他角色。 Management包括SquadLeaderFinance

AspNetUserRoles上分配这些时,我不想列出每个用户的每个组合。有没有办法让一个角色成为一组角色或层次结构?因此,当我运行User.IsInRole("Finance")时,已经被分配了SystemAdmin角色的用户会是这样吗?感谢。

1 个答案:

答案 0 :(得分:3)

假设这些角色是“按原样”并且这里的角色列表都是它们的全部,那么您可以将其转换为基于标志的枚举,并且一组角色的表示可以作为整数存储在db中。

以下是它的工作原理......

public enum Role
{
   Finance = 1
   General = 2
   SquadLeader = 4
   Management = 8 
   SystemAdmin = 16
}

将此应用于我的业务逻辑时,我可以说像...这样的东西。

var genAndSysAdmin = 18;
var genAndSysAdminFlags = Role.General || SystemAdmin;

使用此方法,您可以在用户对象上使用“Role”类型的“RoleFlags”变量,并执行类似...的检查。

User.Roles.HasFlag(Role.Management) 

...检查用户是否处于给定角色。 换句话说,在您的示例中,如果用户具有sysAdmin时具有所有其他角色,则flags值将为...

var allRoles = 16 + 8 + 4 + 2 + 1;

...基本上这就像一个简单的位图。

无论其!

我们不建议以这种方式设计我们的安全模型。

相反,我们应该创建一个普通的角色结构,但同时也允许角色拥有角色的子集合和父角色。

这将允许更典型的设计工作类似于LDAP / Active Directory类型设置......

public class Role
{
    [Key]
    public Guid Id { get; set; }
    [ForeignKey("Parent")]
    public Guid ParentId { get; set; } 
    [Required]
    public string Name { get; set; }
    public virtual Role Parent { get; set; }
    public ICollection<User> Users { get; set; }
    public ICollection<Role> Children { get; set; }
}

public class User 
{
   [Key]
   public Guid Id { get; set; }
   ...
   public ICollection<Role> Roles { get; set; }
}

然后我们设置这样的数据......

new Role { Id = 1, Name = "SystemAdmin" }
new Role { Id = 2, Name = "Management", ParentId = 1 }
new Role { Id = 3, Name = "SquadLeader", ParentId = 2 }
...

...以这种方式工作允许您以灵活的方式继承任何给定父角色中所有子角色的权限级别,并将您的权限视为您尝试模拟的层次结构,同时采用更典型的模式并允许您在将来添加新角色。