8

我一直在为不同的 MVC 框架做很多教程,在 Controller 中进行授权似乎很典型。为什么?

我的想法是控制器应该只用于编排模型操作、处理重定向和处理错误事件。这些是依赖于特定请求的东西。将授权放在控制器中似乎每当您在不同的控制器操作或不同的控制器中使用相同的模型操作时,您都必须复制授权。如果 Auth 在模型中,则您对对数据执行操作或状态更改有一致的要求。

我一直在谷歌搜索并查看其他问题,例如授权应该是模型还是控制器的一部分?但我真的不明白为什么这是公认的约定。

我是否缺少将授权放在模型上的控制器中的特定原因?

总结评论中的要点:

  • 控制器负责改变模型层和当前视图的状态。没有其他的。
  • 授权属于执行操作的地方,如果您遵循严格的 MVC 模式,这很可能是模型,并且控制器当然不负责授权使用模型操作。
  • Cookie 应该像任何其他数据存储一样对待:在模型中抽象和使用,而不是直接由控制器使用。
  • 身份验证和授权是独立的问题,尽管它们通常都在模型层中,因为它们通常涉及对数据存储中的值(例如 cookie)的检查。
4

3 回答 3

9

我是否缺少将授权放在模型上的控制器中的特定原因?

好吧,我能想象的最常见的原因是懒惰。我并不是说在道德上,将一些授权概念放在更接近具体请求的层中,然后在模型层上进行差异化访问要容易得多。获得模型的授权是一个更高的设计。

为了在答案中添加一些更实用的建议,我认为您应该为每个程序分析您希望在何处以及要引入授权的内容。对此的需求可能(非常)不同。

那么只有在下一步中,您才应该考虑哪种设计最有利于引入授权和身份验证来满足这些需求。

于 2013-10-18T19:22:25.453 回答
2

在 MVC 方法中,您需要将安全性放在以下位置:

  1. 无法规避
  2. 可以轻松配置、管理和更新

事实上,这适用于任何架构/类型的应用程序。

具体来说,在 MVC 中,假设您将授权放在视图中。例如,您决定通过启用/禁用按钮来控制谁可以批准交易。如果不允许,您视图的用户将无法批准交易。现在想象一下,您通过 API 而不是视图公开您的控制器。现在需要在 API 层重新实现批准授权检查。

这个例子表明你最好将授权从视图/不同的端点转移到一个公共的中心点——你的控制器。

同样,如果您想控制对大量数据(例如医疗记录)的访问,您最好将授权放在模型中。这既是出于性能原因,也是出于安全原因:您宁愿让控制器处理更少的数据,并且您应该始终努力保护尽可能接近敏感数据的来源。

请注意,同时在视图、控制器和模型中使用授权钩子/检查可能会带来完全增强的体验。将视图中的授权视为“安全/可用性”机制,用户仅根据其权限在屏幕上显示那些相关的菜单和小部件。如果他们是恶意的并且知道如何绕过 UI 到达控制器,那么那里的授权仍然会启动。

最后,一般来说,您希望将非功能性需求/逻辑与功能性需求/逻辑解耦。就像您没有在代码中实现日志记录而是使用可配置框架(例如 Log4J)或者您依赖容器进行身份验证(例如 Apache Tomcat 中的 HTTP BASIC),您希望使用外部化授权框架,例如基于声明的授权Microsofct MVC4 世界、Java 中的 Spring Security、Ruby 中的 CanCan 或 XACML,它是与 SAML (OASIS) 相同的主体的标准部分,它允许您将授权应用于任何类型的应用程序和任何层。

于 2013-10-19T07:09:19.837 回答
1

授权作为一个完整的过程应该涉及到:控制器层和模型层。

但是,所有的 logc(SQL 查询等)都应该发生在模型中。控制器是视图(表示)和模型之间的一种中间层。但是,您根本无法从该方案中丢弃 Controller,因为 Controller 负责处理 Sessions 和 Cookies。没有这两件事,您的所有身份验证/授权逻辑都是无用的,因为它本质上是无状态的。会话和 Cookie 为其带来状态。此外,正如您正确提到的,Controller 负责重定向。

于 2013-10-18T19:19:26.837 回答