为什么权限授权很难?- osohq


授权存在根本性的紧张关系。是业务逻辑还是授权逻辑?它应该在应用程序中,还是分开?
两年前,我和我的联合创始人开始为基础设施构建安全工具。我们一直听说应用程序开发人员正在构建自己的授权工具。起初我们有点怀疑。人们多年来一直在建立授权。这不是一个解决的问题吗?但它一直出现。(注:我是Oso 的联合创始人兼 CTO,Oso是一家构建应用程序授权框架的公司。)
随着我们与更多的工程团队会面,我们听到了一系列的回应。
一些团队告诉我们,“我们只花了 18 个月的时间来构建授权服务。” 其他人说,“授权是我们核心业务逻辑的一部分,我们永远无法将其拆分。” 一些人说,“我们的要求很简单”,而另一些人说,“我们的系统是疯狂的定制。”
双方都对。
当时,授权在科技圈并不是特别流行。快进到今天,AirbnbCartaSlackIntuit都在撰写有关他们构建的内部授权系统的博客文章。突然间,授权似乎是一个和迁移到 Kubernetes 一样酷的话题!
现在是讨论授权困难的原因、解决它的一些方法以及相关权衡的好时机。这就是我将在这篇文章中介绍的内容。TL; 博士

  1. 强制执行授权很困难,因为它需要在很多地方发生。控制器、数据库映射器、路由器和用户界面都需要强制执行授权。因此,适用于所有情况的现成方法有限。
  2. 决策架构很难,因为您想将授权与应用程序分开,但很多授权数据也是应用程序数据。当需要做出决定时,单体可以检查自己的数据库,但是如果您想将授权整合到一个单独的服务中会发生什么?许多现成的解决方案专注于分离——协调它并保持一切同步也很有挑战性。
  3. 建模授权也很难。想出第一个用例很容易——roles在数据库中添加一个表可以工作一段时间。但是很难从简单开始,然后根据需要逐渐增加复杂性。并且很难制作出易于上手的强大功能。可用的选项通常在频谱的一端或另一端出错。

 
三项授权
我们可以将任何授权系统分解为三个基本部分:执行、决策机制和建模。这个 Ruby 小片段包含所有三个:
unless user.admin?
  raise Forbidden, "you must be an admin to update this post"
end

  • 执行权限

强制执行是您的应用程序对授权决定实际执行的操作。一旦您的应用决定拒绝访问,它如何向用户显示? 
执行权限面临的挑战是:没有单一的地方或单一的方法可以实现执权,从数据访问层一直显示到客户端接口都有执行点。
  • 决策

授权决策回答了这个问题:是否允许用户在此资源上执行此操作?决策由逻辑(管理员可以更新)和数据(user对象)组成。
最佳实践是将决策逻辑与应用程序代码分开。但是决策数据通常由授权数据(例如用户具有什么角色)和应用程序数据(例如帖子的作者)组成。决策逻辑如何访问应用程序数据?超越简单的单体架构的任何东西都使这个问题难以回答。
  • 建模

建模是我们将授权逻辑的各个部分分组为更高级别概念的方式。例如,采用上面的代码片段user.admin?。这意味着Users 可以有一个被调用的角色admin,并且拥有该角色会授予用户一定数量的权限。那是一个模型!
大多数应用程序从一个简单的授权模型开始,但随着时间的推移变得复杂。从简单的规则开始,然后演变为涉及关系和属性的更细粒度的权限是很自然的。
结果是简单系统(易于开始,让您快速上手)与可以处理更多复杂性(具有大量选择并且有时学习曲线更陡峭)的系统之间存在紧张关系。

详细点击标题