假设有一个对象TaskList
,它只能由其所有者编辑和删除。其他用户只能接受任务并更新其状态。
我想到了以下选项:
- 检查 Web 应用程序控制器中的所有权和访问权限
- ,让存储库返回代理对象,该对象在某些操作上引发异常,但控制器(或视图)仍然需要知道哪些操作(以表单形式)链接或表单字段)应该是可见的,
- 将调用者(用户)传递给域对象的方法,以便域对象可以自行检查调用者是否被允许。
使用的技术是Java。
还有其他/更好的想法吗?
有关安全和 DDD 的有趣文章
我现在已经接受了自己的答案,因为那是我实际使用的,但欢迎进一步的建议。
Let's say there is an object TaskList
which can be edited and deleted only by its owner. Other users should only by able to take a task and update its status.
The following options come to my mind:
- check the ownership and access in the controller of the web application
- let the repository return proxy object which throws exception on certain operations, but the controller (or view) would still need to know which actions (in form of links or form fields) should be visible
- pass the caller (user) to the method of the domain object, so that the domain object can itself check whether the caller ist allowed or not.
The used technology is Java.
Any other/better ideas?
Interesting articles about security and DDD
I have accepted my own answer now, because that is what I actually use, but further suggestions are welcome.
发布评论
评论(2)
我不会将所有权/权限模型编码到
TaskList
域对象中。这种业务逻辑应该是外部的。我也不喜欢代理对象的想法。虽然它肯定会起作用,但它会混淆调试,并且至少在这种情况下会变得不必要的复杂。我也不会在控制器中检查它。相反,我会创建一个业务逻辑对象来监督
TaskList
的权限。因此,TaskList
将有一个所有者字段,但您将有一个执行业务逻辑的外部访问器。类似于:如果您需要要求
TaskList
对象上的所有操作都通过访问器,那么您可以创建一个工厂类,它是唯一使用包构造函数创建TaskList
的类,或者某物。也许工厂是唯一会使用 DAO 从数据存储中查找TaskList
的工厂。但是,如果以这种方式控制的方法太多,那么代理可能会更容易。在这两种情况下,都建议将
TaskList
设为接口,并由代理或访问器隐藏实现类。I would not encode the ownership/permissions model into the
TaskList
domain object. That sort of business logic should be external. I also don't like the idea of a proxy object. Although it would certainly work, it would confuse debugging and is, in this case at least, unnecessarily complex. I would also not check it in the controller.Instead I would create a business logic object which oversees the permissions for
TaskList
. So theTaskList
would have an owner field but you would have at external accessor which would do the business logic. Something like:If you need to require that all operations on
TaskList
objects go through accessors then you could create a factory class which is the only one who createsTaskList
using package constructors or something. Maybe the factory is the only one who would use the DAO to look up theTaskList
from the data store.However, if there are too many methods to control in this fashion then a proxy might be easier. In both cases having
TaskList
be an interface would be recommended, with the implementation class hidden by the proxy or the accessor.我发现按照“Gray”的建议为每个受保护的域类创建访问器类不必要地复杂。我的解决方案可能并不完美,但使用简单,而且更重要的是健壮。你不能忘记使用某个物体或检查外面的情况。
Guard 知道当前用户(例如来自本地线程),并将其与作为参数传递给allowFor(owner) 的所有者进行比较。如果访问被拒绝,将引发安全异常。
这是简单、健壮的,甚至易于维护,因为如果底层身份验证发生变化,则只需更改防护措施。
I found it unnecessarily complex to create accessor classes for each protected domain class as suggested by 'Gray'. My solution is probably not perfect, but simple to use and - more important - robust. You cannot forget to use a certain object or to check conditions outside.
The
Guard
knows the current user (from a thread local for example) and compares it to the owner passed as parameter toallowFor(owner)
. If access is denied a security exception will be thrown.That is simple, robust and even easy to maintain since only the guard has to be changed if the underlying authentication changes.