在DDD中划分授权和强制执行参考规则之间的界限?

时间:2014-05-21 22:26:52

标签: associations authorization domain-driven-design cqrs business-rules

域名示例:

1

class Customer {
    public $id;
    public $purchaseLimitReached = TRUE;
}

class Order {
    public $customer;

    public function Order(Customer $customer) {
        if($customer->purchaseLimitReached === TRUE) {
            throw new Exception('Order cannot be created, customer   
                has reached his limits!');
        }
    }
}

2

class User {
    public $email;
    public $emailOwnershipVerified = FALSE;
}  

在案例1中,订单不能作为参考的规则是否已达到其购买限额的客户成为域的一部分,在订单对象中?或者此规则应该是授权的一部分,是否在域外处理?

在案例2中,如果用户没有自己(电子邮件),他对域中的任何关联/引用没有权利。他无法对身份/隐藏数据进行身份验证,发布,评论甚至查看。域对象是否应该对用户强制执行有效的引用/关联的检查?或者,用户已经验证自己的验证是否属于授权的一部分,再次在域外?

3 个答案:

答案 0 :(得分:1)

这显然是授权问题,您希望将其分开。让我解释一下

  • 数据是并且应该始终与业务逻辑无关。

  • 如果您永远在用户,自定义和订单之间存在关系,那么您的数据存储无法拒绝这种关系。

  • 可以这样想:数据就是事实。今天是星期四,世界上没有任何商业主管可以改变这种状况。如果它决定在星期四我们对我们的产品收取2倍的费用,那么我们的数据不应该知道,因为业务规则可能会发生变化。改变事实要困难得多,而且只有在可编辑媒体的世界里才有可能。

  • 源代码受版本控制。数据本质上不是。您通常无法恢复数据。

但是,您有合法的需要限制对数据的访问。今天,乔#'是管理员,可以访问所有内容。明天,他会降级并失去他的大部分特权。他仍然是乔,他过去创造的所有客户和订单仍应与他联系,但他现在再也看不到了。

您需要身份验证/授权层。一旦您证明用户是“Joe'你需要知道他可以访问什么。

这不是因为佯装,而且这里的失败几十年来一直是安全问题的核心。刚才开始形成一些真正的可移植架构和库来做这类事情。

Spring security非常强大但仅限于JVM。但是,您可以将模型移植到您喜欢的任何平台,但这很复杂。

另请查看this list of computer security models

所以,坦率地回答你的问题: 让域对象模拟潜在关系并应用安全层。

更实际地,找到可以从可信提供商集成的安全层。使用Google OAuth或OpenID或任何不必实施的内容。你会做错的。

答案 1 :(得分:1)

长话短说,请考虑授权主要是作为业务破产,并为您的域建立模型以反映所有这些规则。真正的授权和业务规则之间的界限非常薄,但是应该尝试忘记授权,并尝试主要考虑业务规则。授权是一个技术问题,在我看来是一个非常薄的层。

答案 2 :(得分:0)

我认为您可以在纯域名之上引入域名授权层,并按照域名进行操作。在纯域中,任何操作和引用都是经过授权的,当授权安全性“关闭”时,它将以这种方式工作,因为纯域不依赖于授权层。授权“打开”后,您将执行授权服务执行的特定于安全性的检查。它的外观最终将取决于您将用于“拦截”域行为以执行授权规则的机制(域对象/服务装饰器,特定安全方面的编织等)。 / p>

还要看一下类似问题的答案:https://stackoverflow.com/a/23300337/1512875