您如何将身份验证、角色和安全性融入您的 DDD?
Posted
技术标签:
【中文标题】您如何将身份验证、角色和安全性融入您的 DDD?【英文标题】:How do you weave Authentication, Roles and Security into your DDD? 【发布时间】:2010-10-27 18:24:01 【问题描述】:您如何在 C# 领域驱动设计项目中实现角色和安全性?关于它应该由调用应用程序(ASP.NET MVC)还是在域模型本身(模型实体和服务)中实现,我们存在一些激烈的争论。有些人认为它应该在网站本身,因为那里已经存在身份验证。但这意味着每次与核心业务系统集成时都必须重新实现安全性。
例如:管理员应该能够在系统中执行几乎任何操作,例如编辑和删除记录(即他们可以删除用户的订单)。另一方面,用户应该只能编辑和删除他们自己的记录(即他们可以在他们的购物车中添加/删除项目)。
顺便说一句,这是一篇关于该主题的不错的论文,涵盖了有关 DDD 和安全性的 7 种不同场景:
Security in Domain-Driven Design
第4章安全服务设计场景 4.1 场景一:安全服务作为常规服务 4.2 场景 2:UI 中嵌入的安全性 4.3 场景三:安全服务封装领域模型 4.4 场景 4:安全服务作为 UI 的网关 4.5 场景 5:安全服务作为 UI 的适配器 4.6 场景 6:AOP 与适配器集成的安全服务 4.7 场景 7:与 AOP 集成的安全服务我个人倾向于使用 PostSharp 进行 AOP,但之前并没有做过太多的事情,所以我犹豫要不要迈出这一步。
【问题讨论】:
哇,PostSharp 看起来很酷,我以前没听说过。 对我来说,提供的文档链接中提供的选项是此问题的最佳答案。我喜欢第 4.3 节中的场景。 请问Githup上这个有趣的论文是否有更多的实现细节? 【参考方案1】:不要忘记运行时已经内置了一个抽象的安全/用户系统 - 主体(请参阅此existing answer - 请注意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,没有人会阻止您...
【讨论】:
当用户不是该特定订单号的所有者时,如何防止他们形成自己的 url /Order/Delete/42?我了解基于角色限制访问,但这不包括所有权,是吗? 确实没有(本身);您需要根据个人请求数据选择角色。 因此,除了 PrincipalPermission 属性提供的角色授权之外,我还需要执行所有权检查,例如 if (!order.IsOwnedBy (User.Identity.Name)) 扔 ? 是的,我认为这是公平的 - 尽管if(!order.IsOwnedBy(...) && !UserUtility.IsInRole(Roles.SUPER_ADMIN)) throw
可能会考虑管理员访问等问题。以上是关于您如何将身份验证、角色和安全性融入您的 DDD?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 AWS API Gateway 设置 OAuth2 身份验证提供程序?