详解微服务中的三种授权模式

作者|GrahamKaemmer
译者|Rayden
审校|王强
在过去的5个月里 , 我与50多家公司讨论了他们的授权系统 。 其中超过一半的公司以某种形式使用微服务 , 我对它们带来的授权挑战非常感兴趣 。 在面向服务的后端进行授权这一问题上 , 似乎没有公认的最佳实践 。 我与很多团队进行了交谈 , 有的团队将用户角色附加到身份验证令牌上 , 有的将所有内容存储在专门用于授权的图数据库中 , 还有的团队在Kubernetes边车(sidecars)中自动执行授权检查 。 这些解决方案中都沉淀了数月或数年的工程工作 , 每个团队都发明了自己的轮子 。 这是为什么?
当你有一个单体应用时 , 你通常只需要访问一个数据库来决定是否允许用户做某些事情 。 单体应用的授权策略本身不需要太关心在哪里找到数据(比如用户角色)——你可以假设所有数据都可用 , 如果需要加载额外数据 , 它也可以很容易地从单体应用数据库中获取 。
但是这个问题在分布式架构中变得困难了许多 。 也许你正在将单体应用拆分为多个微服务 , 或者你正在开发一个新的计算密集型的服务 , 在运行作业之前需要检查用户权限 。 现在 , 决定谁可以做什么的数据可能不那么容易获取 。 你需要新的api , 以便你的服务能够相互谈论权限:“谁是这个组织的管理员?谁可以编辑这个文档?他们可以编辑哪些文档?”为了在服务A中做出决策 , 我们需要服务B中的数据 , 服务A的开发人员如何请求这些数据?服务B的开发人员如何使这些数据可用?
这些问题有很多答案 , 所以我试图将这些答案归纳为几个广泛的模式 。 这些模式不一定能覆盖所有解决方案(解决方案的世界很复杂) , 但我发现它们能帮助我与不同的人谈论他们所构建的东西 。 当我与一个新团队进行对话时 , 它们让我更容易对解决方案进行分类 。
在构建微服务时 , 我看到了处理授权数据的三种主要模式 。 我将在这篇文章中讨论这三种方法:
将数据留在原处 , 让服务直接请求它 。
使用网关将数据附加到所有请求 , 以使其随处可用 。
将授权数据集中到一个地方 , 并将所有决策转移到那个地方 。
为什么微服务中的授权更困难?
详解微服务中的三种授权模式】让我们以某个授权场景为例 , 这是一个用于编辑文档的应用程序 。 它很简单 , 但应该能说明问题:
有用户、组织和文档 。
用户在组织中拥有角色 , 包括成员和管理员 。
文档属于组织 。
如果用户在组织中的角色为成员 , 则可以阅读文档 。
如果用户在组织中的角色为管理员 , 则可以阅读或编辑文档 。
在一个单体应用中 , 用一种清晰的方式表达这种逻辑并不太难 。 当你需要检查用户是否可以阅读文档时 , 你可以检查该文档属于哪个组织 , 加载该组织中用户的角色 , 并检查该角色是成员还是管理员 。 这些检查可能需要额外的一两行SQL语句 , 但数据都在一个地方 。
当你将应用程序拆分为不同的服务时 , 会发生什么情况?也许你已经剥离了一个新的“文档服务”——现在 , 检查特定文档的读权限需要检查位于该服务数据库之外的用户角色 。 文档服务如何访问它所需要的角色数据?
详解微服务中的三种授权模式
文章图片
模式1:将数据留在原处
通常 , 最简单的解决方案是将数据留在原处 , 并让服务在需要时请求它所需要的数据 。 对于上述问题 , 你可能认为这是最明显的解决方案 。