您如何将身份验证,角色和安全性编入您的DDD?

Tod*_*ith 11 c# security authentication domain-driven-design roles

如何在C#域驱动设计项目中实现角色和安全性?关于它是应该由调用应用程序(ASP.NET MVC)还是在域模型本身(模型实体和服务)中实现,我们有一些争论.有些人认为它应该在网站本身,因为那是身份验证已经存在的地方.但这意味着每次与核心业务系统集成时都必须重新实现安全性.

例如:管理员应该能够在系统中执行几乎任何操作,例如编辑和删除记录(即他们可以删除用户的订单).另一方面,用户应该只能编辑和删除他们自己的记录(即他们可以在购物车中添加/删除项目).

顺便提一下,这里有一个很好的论文,涵盖了有关DDD和安全性的7种不同场景:

域驱动设计中的安全性

  • 第4章安全服务设计方案
    • 4.1场景1:作为常规服务的安全服务
    • 4.2场景2:UI中嵌入的安全性
    • 4.3场景3:封装域模型的安全服务
    • 4.4场景4:安全服务作为UI的网关
    • 4.5场景5:安全服务作为UI的适配器
    • 4.6场景6:AOP与适配器集成的安全服务
    • 4.7场景7:与AOP集成的安全服务

我个人倾向于使用PostSharp倾向于AOP,但之前没有做过多少工作,我犹豫不决.

Mar*_*ell 7

不要忘记运行时已经内置了一个抽象的安全/用户系统 - 主体(请参阅现有的答案 - 请注意,这GenericIdentity只是一个选项;编写自己的选项非常简单).

您的UI可以根据具体实现来处理创建和分配主体(实际上,IIRC ASP.NET和WCF会自动执行此操作,或者对于winforms/wpf,您可以使用Windows身份,或者(通过Web服务)使用相同的ASP .NET登录).

然后你的业务逻辑只是检查Thread.CurrentPrincipal; 从中您可以获得名称,身份验证方法和角色检查(无需了解角色的实现方式).

运行时还提供内置检查:

    [PrincipalPermission(SecurityAction.Demand, Role = Roles.Admin)]
    public void Foo() {...}
Run Code Online (Sandbox Code Playgroud)

(Roles.Admin您的角色名称的字符串常量在哪里)这将自动检查访问权限,SecurityException如果不在角色中则抛出一个.您还可以通过代码进行检查(如果在编译时未修复角色,则非常有用).

显然,您的UI应检查角色(禁用/隐藏功能),但最好让业务代码强制执行角色,而无需了解UI.

(添加)

我应该提一下,GenericIdentity单元测试很方便.当然,您可以使用自己的安全API,没有人会阻止您...