【发布时间】:2014-06-22 00:42:05
【问题描述】:
我们是一家使用 .NET 技术的小型软件公司。我们有一个自制的框架,起初它似乎适用于我们的一些项目,但现在我们发现了一些问题。
表示层是 ASP.NET MVC 应用程序。服务层是一个单一的 WCF XML 服务,我们将其与多个 ASP.NET MVC 前端一起用于 Intranet 和 Internet 客户端。为了使基础设施任务尽可能透明和自动化,我们使用 Get、GetList、New、Update、Delete 方法实现了有点类似于 REST 的 WCF 服务,这些方法对 DTO(数据传输对象模式)实体进行操作。每个 WCF 方法调用都通过自定义 WCF 行为进行处理,以记录每个请求并控制身份验证和授权。在我们的事件日志中,我们的记录会导致类似这样的报告:
During activity with id {guid-here} User John Doe from IP executed Update operation on entity Foobar. Operation result was Success/DataValidationFailure/AuthorizationFailure/UnknownFailure etc.
也可以通过Give user John Doe permission to execute operation Get/GetList/New/Update/Delete on entity Foobar.等复选框轻松控制授权
我们的业务逻辑开发人员创建实体、NHibernate 映射(现在我们考虑迁移到像 Dapper 这样更轻量级的东西,但这是另一回事),然后将业务逻辑放入我们的业务层 - 方法标记有特殊属性,以便我们的 WCF 服务知道在哪里为每个实体发送请求。本质上,我们拥有带有程序业务逻辑的贫乏领域模型。我知道这不是一个好方法,但对于新手开发人员来说似乎更容易,而且我们团队中有很多人。
我们的 DTO 是某种与单个业务实体不匹配的操作描述符。例如,Update (Foobar) 操作可能对实体 Foo 和 Bar 执行两个业务操作。现在,客户端在事件日志中看到的是用户 John Doe 对实体 Foobar 执行了更新操作。客户一头雾水:“喂,Foobar 那个实体是什么?我知道,我们有 Foo,我们有 Bar,但是当有人在 Foobar 上执行更新请求时,这意味着什么?”如您所见,问题在于,对于客户而言,我们的 DTO 没有多大意义——客户只知道他的业务对象,而不关心我们使用什么 DTO。但另一方面,客户端也不会满足于看到对 Foo 和 Bar 的单独操作,而没有与用户执行的上层操作有任何联系。
授权控制也会出现同样的问题 - 客户端能够在我们的 DTO 上启用/禁用各种类似 REST 的操作,但从业务逻辑的角度来看,这些复选框没有多大意义。这意味着如果用户有权执行Update (Foobar),他自动有权使用实体Foo 和Bar 执行其他操作(在Update (Foobar) 业务方法中编程的内容)。但是客户端可能希望分别控制 Foo 和 Bar 的操作,我们的框架不支持。
总而言之,问题在于目前我们有一个单点用于记录和验证检查 - 它是我们的 WCF 服务,它主要与 DTO 一起使用,而这些 DTO 并不直接映射到我们客户熟悉的业务实体。
解决 log&auth 问题的一个想法是实现类似于 Active Records 模式的东西,其中每个操作都会自动将自身添加到事件日志并检查授权规则。这将允许我们在业务实体级别执行日志记录和授权,这对我们的客户来说是有意义的。这是最好的解决方案吗?我们是否有其他选择来改进我们的日志记录和身份验证,以便它们对我们的客户更有意义,并且仍然将我们的样板代码保持在最低限度?
【问题讨论】:
-
您是否研究过使用 XACML 和基于规则的访问控制完全外部化授权?
标签: .net logging authorization service-layer business-logic-layer