将授权放在服务层而不是 Web API 层

Posted

技术标签:

【中文标题】将授权放在服务层而不是 Web API 层【英文标题】:Placing authorization into the service layer rather than Web API layer 【发布时间】:2018-03-05 22:46:20 【问题描述】:

我正在使用 .NET Core Web API 构建一个 REST API。

我的控制器只是将请求转发到服务层并返回结果

[HttpPost(nameof(Create))]
public async Task<Response<ProviderDTO>> Create([FromBody] ProviderDTO provider)
    => await providerService.CreateAsync(provider);

我现在处于系统中需要开始实施授权的位置。

.NET Core 有 a lot of options 来实现授权,但文档主要在 Web 层的上下文中讨论这些方法(显然是控制器所在的位置)。

我的直觉告诉我,我需要在服务层本身内实现授权,而不是将此授权放在 Web 层。

我的一些推理包括:

    服务层可能会被控制器以外的东西调用(例如,服务调用其他服务,此时与授权无关)。 可以直接对服务授权进行单元测试,而不必依赖为服务前面的每个“层”编写的集成测试。 保存对数据库的多次调用 -- 如果我需要在授权要求中授权文档,如果它通过了,我必须稍后在服务中提取相同的文档。

问题一

IPrincipalIAuthorizationService 注入我的服务并直接在其中处理授权是一种明智的方法吗?然后 web 层将纯粹检查用户是否登录,也许还有一些更简单的基于策略的属性(例如,这个控制器只允许人员策略)

问题二

有没有人可以将我链接到任何资源(我做过研究,但没有太多关于这方面的内容)

PS:关于拒绝服务层的请求,我有一个异常处理中间件,可以将自定义异常转换为 HTTP 响应。因此,如果发生未经授权的请求,我将抛出一些未经授权的异常,最终导致 HTTP 403。

【问题讨论】:

【参考方案1】:

这完全取决于我们所谈论的授权类型以及实现它所涉及的工作量。

一般来说,将您的服务层与 Web 层混合并不是一个好主意,因此请将它们分开。

Web 授权是一回事 - 你在这里说我有一个用户,他是否被允许访问这个端点/页面/任何东西。如果不是,您甚至可以通过根本不调用服务层来节省资源,并且可以在 Web 层中非常早地拒绝请求,并且非常快速地拒绝资源,而不会浪费资源。

接下来,你说的这个服务层是什么?它是真正与数据库对话的那个,还是在你从数据层获得数据后进行一些数据操作的那个?

我的偏好是有一个单独的数据层和授权层。授权层是应用您需要的任何规则然后返回结果的层,这样您就知道是否需要费心去获取任何数据。它不链接到您的 Web 层,不返回 HTTP 代码,一般来说与 UI 方面无关。

这意味着,如果您有多个客户端,例如一个 Web UI 和一个移动 UI,那么两者都将通过这一层,因此这一层级的工作不会重复。

更好的是,您可能想要构建一个负责返回数据的适当 API,然后您所要做的就是从您拥有的任何客户端处理这一件事,然后您就可以在那里处理您的授权。如果您确保可以将授权层与其他任何东西分开调用,而不依赖于其他任何东西,那么您可以从多个地方调用它,并且可以轻松独立地对其进行测试。

这是人们在构建任何东西之前都会考虑的事情,一旦完成其他所有事情,安全性并不是您添加的最后一件事。您在构建产品时要牢记这一点,因为它涉及很多事情,并且会影响您的架构。

所有东西如何组合在一起的图表会有所帮助。

你们有什么样的架构? 您所说的授权涉及程度如何? 我们在谈论什么样的客户?

在此之前有很多问题需要回答。

我再提几点,你发表了一些声明:

服务层可以被控制器以外的东西调用 (例如,服务调用其他服务,这不会是 与授权有关)。

服务授权可以直接进行单元测试,而不是 依赖为每个“层”编写的集成测试 在服务前面。

    如果您正在考虑微服务,也就是许多独立运行的小服务,那么您绝对需要关注安全性,具体取决于这些东西是如何访问和相互通信的。

    这就是你编写授权层的原因,一切都通过它,这是你测试的,而不关心任何 UI 类型的东西。

【讨论】:

以上是关于将授权放在服务层而不是 Web API 层的主要内容,如果未能解决你的问题,请参考以下文章

Web API 业务层架构及其职责

使用 WCF/OData 作为访问层而不是直接使用 EF/L2S/nHibernate 的论点

不使用休眠模板的服务方法

模型层的业务规则

.net n 层身份和服务架构中的授权

远程 API/Web 服务层 MVC 的域逻辑和数据访问