[英]Is this a good data model to implement strongly-typed roles?
是的, 这里和这里都曾问过这个 问题 。 我对我正在考虑的方法在体系结构上是否合理感到好奇。
首先,我尝试描述我希望对对象模型进行的处理:
class Person {
ISet<Roles> Roles { get; set; }
}
class RoleDefinition {
string Name { get; set; }
}
class RoleAssignment {
RoleDefinition Definition { get; set; }
Person Person { get; set; }
}
class UserRole : RoleAssignment {
public virtual string Login { get; set; }
public virtual string Password { get; set; }
}
旨在能够以以下方式使用角色:
// Find all "users" with a matching login
from user in userRolesRepository.FindAll(u => u.Login.StartsWith("abc"))
select user.Person;
为此,我正在考虑以下数据模型
Person table (Id, Name)
RoleDefinition table (Id, Name)
RoleAssignment table (Id, DefId, PersonId)
UserRole table (RoleAssignmentId, Login, Password)
AdminRole table (RoleAssignmentId, ...)
我将UserRole和AdminRole作为连接子映射到NHibernate中的RoleAssignment。
因此,Person与UserRole和AdminRole之间为1:1,UserRole与RoleAssignment之间为1:1,RoleAssignment与RoleDefinition之间为n:1。
我的问题是:这真的是一个好模型吗?
有没有更好的方法来对此建模,而又不会失去每个角色具有强类型可查询属性的能力? 考虑到随着我们的前进,我将在系统中添加更多角色,它将如何扩展?
乍一看,我认为单个用户拥有多个登录名和密码(每个角色一个)是有点奇怪的,除非您假设一个用户始终属于一个角色。 例如,如果我都属于一个名为Accountant
和Salesperson
角色(例如可能发生在小型企业中),则根据上面的定义,我似乎有两个RoleDefinition
,因此,两个登录名和密码。
除此之外,在过去,我已经对此进行了类似的映射。 有一个User
类,它本质上是一个用户配置文件,并具有诸如string UserName
, string HashedPassword
, TimeZoneInfo TimeZonePreference
, ISet<Role> Roles
等ISet<Role> Roles
,以及LogOn(string password)
方法。
我的User
类的LogOn()方法会执行诸如更新FailedLogonsCount
属性或TemporaryLockoutLiftedAtUtc
属性之类的操作,具体取决于是否对输入的密码进行散列处理是否成功对存储的密码进行哈希处理,或者是否返回实现IPrincipal
的非持久对象这是标准的.NET接口 。
从这个意义上讲,我区分了用户的个人资料( User
类)和它们的身份验证/授权令牌(实现IPrincipal
和IIdentity
非持久类),以便他们可以参与整个应用程序中使用的各种[Authorize]
和Thread.CurrentPrincipal
方案。 .NET框架)。 当User
实例创建实现IPrincipal
的对象时,它只是将用户角色的副本作为字符串数组传递,以便IPrincipal
的IsInRole()
方法将起作用。
这意味着我的角色名称本质上是魔术的知名字符串,实际上是Roles数据库表中的唯一键。 但是我认为这没有很多办法。 确实,我的Role
类如下所示:
class Role {
int? Identity { get; } // database identifier that I never really look at
string RoleEnum { get; } // the "enumeration" that is
// the well-known string, used in IsInRole()
string RoleName { get; } // a human-friendly, perhaps
// localizable name of the role
}
对于每种角色类型,我没有单独的子类。 作为类的UserRole
和AdminRole
是否真的在本质上具有单独的行为 ? 我认为它们只是通用Role
类的不同数据点,因此您不需要为每个类分别使用单独的子类。
当您向系统中添加角色时,您将需要使用该角色的更新检查重新编译整个shebang(这是我的工作,我不希望经常添加角色),或者,如果真的很想花哨, Role
类可以包含一组Permission
对象或其中的一些对象,并且您的代码可以只询问role.AllowsUserToDoThis()
是否为role.AllowsUserToDoThis()
并将所有权限检查在一个地方。 因此,配置角色的权限集将允许您在系统运行时编辑细粒度的访问控制,但是您将失去.NET提供的基于角色的安全模型的简单性。
您可能已经猜到有百万种方法可以这样做,但是希望这是一些有用的反馈。 祝好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.