如何在 C# 领域驱动设计项目中实现角色和安全性?关于它是否应该由调用应用程序 (ASP.NET MVC) 实现还是在域模型本身(模型实体和服务)中实现,我们存在一些激烈的争论。有些人认为它应该在网站本身中,因为那里已经存在身份验证。但这意味着每次与核心业务系统集成时都必须重新实现安全性。
举个例子:管理员应该能够在系统中执行几乎任何操作,例如编辑和删除记录(即他们可以删除用户的订单)。另一方面,用户应该只能编辑和删除自己的记录(即他们可以从购物车中添加/删除商品)。
顺便说一下,这是一篇关于该主题的很好的论文,涵盖了有关 DDD 和安全性的 7 种不同场景:
我个人倾向于使用 PostSharp 进行 AOP,但之前没有做过太多工作,所以我犹豫是否要迈出这一步。
不要忘记运行时已经内置了一个抽象的安全/用户系统 - 主体(请参阅此现有答案 - 请注意
GenericIdentity
只是一个选项;编写自己的系统非常简单)。
您的 UI 可以根据特定实现来处理创建和分配主体(事实上,IIRC ASP.NET 和 WCF 自动执行此操作,或者对于 winforms/wpf,您可以使用 Windows 身份,或者(通过 Web 服务)相同ASP.NET 登录)。
您的业务逻辑只需检查
Thread.CurrentPrincipal
;从中您可以获得名称、身份验证方法并检查角色(无需知道角色是如何实现的)。
运行时还提供内置检查:
[PrincipalPermission(SecurityAction.Demand, Role = Roles.Admin)]
public void Foo() {...}
(其中
Roles.Admin
是角色名称的字符串常量)这将自动检查访问权限,如果不在角色中,则抛出 SecurityException
。您还可以通过代码进行检查(如果角色在编译时未固定,则很有用)。
显然,您的 UI 应该检查角色(以禁用/隐藏功能),但最好拥有业务代码强制角色,而无需了解 UI。
(已添加)
我应该提到
GenericIdentity
对于单元测试来说很方便。当然,您可以扮演自己的安全API,没有人会阻止您......