DDD - 实现授权不变量

时间:2018-05-21 20:29:35

标签: c# authorization domain-driven-design

我是DDD的初学者,对如何实现特定域用例的授权不变量有疑问。

我有两个子域名:成员资格和身份。身份处理身份验证和管理用户和角色。

有问题的子域名是会员资格。会员可以拥有多种状态。激活成员时,有三个不变量:

  1. 章节管理员只能激活其章节中的成员
  2. 章节管理员只能激活非活动成员。
  3. 系统管理员可以激活任何状态的任何成员。
  4. 用户有角色。这种情况的角色是系统管理员和章节管理员(单章)。

    所以我有一个应用程序服务。用户ID存储在.Net Identity中,但我觉得保持应用程序服务不知道.Net Identity是一个好主意?

    public void ActivateMember(UserId userId, MemberId memberId)
    {
         //This handles invariants 1 & 3
         memberAccess.DoesUserHaveAccessToMember(userId, memberId);
    
         //But how to I handle 2?
    
         //here is the call into the domain
         commands.Handle(new ActivateMember(memberId);
    }
    

    如何处理2?命令处理程序是一个域服务,它只加载成员,调用其激活成员并将其保留。来自身份域的身份验证服务是否应该被推下去?我可以在上面的类中实现2,但是我必须从存储库加载两次成员。那不好吗?

1 个答案:

答案 0 :(得分:1)

  

身份处理身份验证和管理用户和角色

因此,Identity处理身份验证和授权;拥有roles只是应该从其他有界上下文中隐藏的实现细节。这意味着Membership BC不应该关心授权是如何工作的,只是它有效。因此,为了隐藏它,Authorization BC应该发布如下界面:canUserActivateMember(userId,memberId)

现在,棘手的部分是在两个BC中都有members的概念,但它意味着其他的东西:

  • Membership BC中,成员包含特定于此域的(很多)属性和行为,例如IDNameStatus,{{1} },进入/离开俱乐部,以及该领域的相关内容
  • Gender BC的
  • 中,成员只包含AuthorizationIDChapter,没有任何行为。 Status属性由来自Status BC的反腐败层同步(以cron或其他形式)。

因此,来自Membership BC的ActivateMember服务应如下所示:

Membership

public void ActivateMember(UserId userId, MemberId memberId) { //This handles invariants 1, 2 & 3 if(!authorization.canUserActivateMember(userId,memberId)) { throw ExceptionOrSomething; } //here is the call into the domain commands.Handle(new ActivateMember(memberId); } BC中,方法Authorization可能如下所示:

canUserActivateMember

所以,你有两个public boolean canUserActivateMember(UserId userId, MemberId memberId) { var user = userRepository.load(userId); var member = memberRepository.load(memberId); if(user.isSystemAdministrator()){ return true; } if(user.isChapterAdministrator() && member.hasChapter(user.getChapter)){ return true; } if(user.isChapterAdministrator() && member.isInactive()) { return true; } return false;//the default } 类,每个BC一个,但具有不同的属性和行为。

相关问题