11

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

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

顺便说一句,这是一篇关于该主题的不错的论文,涵盖了有关 DDD 和安全的 7 种不同场景:

领域驱动设计中的安全性

  • 第四章 安全服务设计场景
    • 4.1 场景一:安全服务作为常规服务
    • 4.2 场景 2:UI 中嵌入的安全性
    • 4.3 场景三:封装领域模型的安全服务
    • 4.4 场景四:安全服务作为 UI 的网关
    • 4.5 场景 5:安全服务作为 UI 的适配器
    • 4.6 场景六:AOP 与适配器集成的安全服务
    • 4.7 场景七:与AOP集成的安全服务

我个人倾向于使用 PostSharp 的 AOP,但之前没有做过太多的工作,所以我犹豫要不要迈出这一步。

4

1 回答 1

7

不要忘记运行时已经内置了一个抽象的安全/用户系统——主体(参见这个现有的答案——注意这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,没有人会阻止您...

于 2009-05-20T20:51:35.253 回答