代码之家  ›  专栏  ›  技术社区  ›  Ragesh

这是实现强类型角色的好数据模型吗?

  •  0
  • Ragesh  · 技术社区  · 16 年前

    here here . 我很好奇我正在考虑的方法是否在架构上是合理的。

    首先,让我描述一下我希望能够对我的对象模型做些什么:

    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中的roleasignment。

    所以,在Person和UserRole以及AdminRole之间是1:1,在UserRole和roleasignment之间是1:1,在roleasignment和RoleDefinition之间是n:1。

    我的问题是:这真的是个好模型吗?

    有没有更好的方法来建模而不失去每个角色具有强类型、可查询属性的能力?考虑到随着我们的发展,我将在系统中添加更多的角色,它的规模会有多大?

    1 回复  |  直到 9 年前
        1
  •  3
  •   Nicholas Piasecki    16 年前

    乍一看,我觉得一个用户有多个登录名和密码有点奇怪,每个角色一个,除非你假设一个用户总是属于一个角色。例如,如果我都属于 Accountant Salesperson ,例如在小企业中可能发生的情况,根据上面的定义,我将拥有两个 RoleDefinition 因此,有两个登录名和密码。

    除此之外,在过去,我也做过类似的映射。有一个 User string UserName , string HashedPassword , TimeZoneInfo TimeZonePreference , ISet<Role> Roles 等,以及 LogOn(string password)

    我的LogOn()方法 用户 类执行诸如更新 FailedLogonsCount TemporaryLockoutLiftedAtUtc 属性等等,这取决于对传入密码与存储的密码进行哈希运算是否成功,或者它返回实现 IPrincipal ,这是一个 standard .NET interface .

    在这个意义上,我区分了用户的配置文件 用户 类)及其身份验证/授权令牌(实现 原则 IIdentity [Authorize] Thread.CurrentPrincipal 在整个.NET框架中使用的方案)。当 用户 实例创建实现 原则 ,它只是将用户角色的副本作为字符串数组传递,以便 IsInRole() 方法会奏效的。

    这意味着我的角色名本质上是神奇的、众所周知的字符串,实际上是角色数据库表中的唯一键。但我觉得没什么办法。的确,我的 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 行为 角色 类,因此您不需要为每个子类单独创建子类。

    角色 Permission 对象或其中的某些对象,您的代码可以只询问角色 role.AllowsUserToDoThis()

    正如你可能已经猜到的,有上百万种方法可以做到这一点,但希望这是一些有用的反馈。祝你好运!