领域模型中是否应考虑安全问题?

6

我正在开发一个基于MVVM的Winforms项目(.NET 4),与安全相关,应用程序通过Active Directory进行身份验证,然后使用基于角色的安全性来确定对程序不同部分的访问权限。在大多数地方,安全性是使用PrincipalPermissionAttribute实现的,如下所示:

<PrincipalPermissionAttribute(SecurityAction.Demand, Role:="Managers")> _
Public Sub Save() Implements IProductsViewModel.Save
    mUOW.Commit()
End Sub

正如您从接口实现中可以看出的那样,这个特定的Sub位于ViewModel中。PrincipalPermissionAttribute正在检查当前用户(Thread.CurrentPrincipal)是否处于Manager角色。
这引出了我的问题:安全检查(如上所述)应该在Domain Model中进行吗?
当我自己思考时,我有两种相互冲突的观点:
1)尽可能使领域模型无知于其他关注点,以减少复杂性和依赖性。(保持安全性,或者在ViewModel中实现)。
2)领域模型在某种程度上是“最后一道防线”的地方。如果我在领域模型中实现安全性,那么我知道即使另一个层次的安全性失败,领域模型也应该能够捕获到它。
那么,你认为是在领域模型中实现安全性还是不实现呢?
3个回答

4

有两种安全性。

第一种是纯技术性的 - 比如“所有流量都应该通过https传输”或“只有特定服务才能触及数据库”或“只有特定进程才能操作文件系统/注册表”。

第二种与领域紧密相关。比如“只有拥有秘书角色的用户才能访问付款历史记录”或“未授权用户不应该能够访问会计信息”。

第一种应该与领域解耦。第二种应该存在于领域内部。


很棒的答案,我认为这正是我最初思考的方向。当遵循这种方法时,如何保护可能没有真正领域表示(例如报告)的只读操作?您是否有“报告”实体,还是在其他级别进行保护? - Casey Wilkins
我会有一个名为“CanSeeReports”的用户权限,它将被负责显示报告的进程用于授权。如果报告本身知道如何呈现自己,则更好-这样报告始终可以确保授权。但是我可以接受这种隔离丧失。 - Arnis Lapsa
当你提到"domain"时,是指领域模型,例如"Order"类,还是指一种安全服务,该服务可以验证当前用户是否拥有特定的权限?我认为,在某些情况下,安全服务可能没有足够的信息,这种情况下责任应该落在领域模型上。 - Sudarshan
@Sudarshan的课程或服务并不定义您的领域,而是您的想法。 - Arnis Lapsa
我同意,但我的问题更加技术化,责任应该由“领域模型层”还是应用层承担,考虑分层架构的概念。 - Sudarshan

1

个人认为,这个问题似乎属于服务层。假设应用程序将通过服务层到达域,并且您可以轻松地拥有一个非域服务来验证用户的角色以进行提交。

我这样做的原因是基于这样的理论:越接近域的核心,调用堆栈就越昂贵。在更高的级别上防止滥用/误用域意味着更好的响应能力和凝聚力。

此外,假设要求发生变化,另一个角色现在可以执行相同的操作。将所有这些都保留在服务层中意味着您也不会更改应该较少更改的代码。至少在我所做的事情中,从中获得的积极收益是,越接近核心,代码更改的可能性就越小。这意味着您还可以减少您的更改对其他您不打算更改的区域产生“波及”的可能性。

更广泛的问题是,不针对个人,我不喜欢在ViewModel中放置任何类型的数据访问。 ViewModel旨在成为模型的表示,特定于实现。 这些对象应尽可能轻量级。 例如,如果对产品进行更改,则更改将通过服务传递,然后到达存储库,在那里可以向工作单元注册,等待提交。

保持安全性不涉及领域的一些非常好的论点,谢谢。至于ViewModel中的数据访问,我理解你的观点并且同意。我正在使用EF 4,我的UOW实际上只是ObjectContext的包装器。我采用“每个ViewModel一个UOW”的方法,例如当View请求新的ViewModel时,ViewModel会带着在存储库拉取实体时创建的UOW。ViewModel所做的任何更改都会被UOW自动跟踪。ViewModel唯一能够对UOW执行的操作就是告诉它提交。 - Casey Wilkins

0

这里有很棒的答案。我想这取决于您的权限系统的细粒度级别。假设我们正在设计一个“任务管理系统”,我们希望用户在“项目”级别上限制可见性。

  • 我们可以设计一个通用的“可读”角色或权限,适用于所有项目。
  • 我们可以更深入地实现类似DAC的系统,回答问题“此用户是否可以读取此特定对象”。这意味着每个“项目”都有自己的“读取权限”,因此不允许我们实现除域级别(或非常接近域级别)以外的其他内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接