限制对DDD中对象所有者的访问

时间:2011-12-09 15:13:51

标签: java security domain-driven-design authorization

假设有一个对象TaskList,只能由其所有者编辑和删除。其他用户应该只能执行任务并更新其状态。

我想到了以下选项:

  • 检查Web应用程序控制器中的所有权和访问权限
  • 让存储库返回代理对象,该代理对象在某些操作上抛出异常,但控制器(或视图)仍然需要知道哪些操作(以链接或表单字段的形式)应该是可见的
  • 将调用者(用户)传递给域对象的方法,以便域对象本身可以检查调用者是否被允许。

使用的技术是Java。

还有其他/更好的想法吗?

有关安全性和DDD的有趣文章

我现在已经接受了我自己的答案,因为这是我实际使用的,但欢迎进一步的建议。

1 个答案:

答案 0 :(得分:2)

我不会将所有权/权限模型编码到TaskList域对象中。那种业务逻辑应该是外部的。我也不喜欢代理对象的想法。虽然它肯定会起作用,但它会使调试混乱,并且在这种情况下至少是不必要的复杂。我也不会在控制器中检查它。

相反,我会创建一个业务逻辑对象来监督TaskList的权限。所以TaskList会有一个所有者字段,但你会有类似的东西:

public class TaskListAccessor {
    private TaskList taskList;
    private User reader;

    public void updateStatus(Status status) {
        // everyone can do this
        taskList.updateStatus(status);
    }

    /** Return true if delete operation is allowed else false */
    public boolean isDeleteAllowed() {
        return taskList.getOwner().equals(reader);
    }

    /** Delete the task.  Only owners can do this.  Returns true if worked else false */
    public boolean delete() {
        if (isDeleteAllowed()) {
           taskList.delete();
           return true;
        } else {
           return false;
        }
    }
    // ... other accessors with other is*Allowed methods
}

如果您需要要求TaskList个对象上的所有操作都通过访问器,那么您可以创建一个工厂类,这是唯一一个使用包构造函数或其他东西创建TaskList的工厂类。也许工厂是唯一一个使用DAO从数据存储中查找TaskList的工厂。

但是,如果以这种方式控制的方法太多,那么代理可能会更容易。在这两种情况下,建议使用TaskList作为接口,实现类由代理或访问者隐藏。