支持分布式基于角色的访问控制 (RBAC) 的授权库
我们的 KFC 项目采用了微服务架构,组件使用各种语言和运行时环境编写,例如 .NET、Ruby 和 Go。 其中许多组件需要能够根据用户的授权状态做出决策:用户的身份,他们所属的角色,能够执行的操作,以及执行操作的对象。
我们需要一种一致的方式在多种独立语言之间使用基于角色的访问控制,我们还需要一种方式来管理权限和访问控制列表 (ACL)
在通用框架中使用 Ruby、Python、PHP 或 Go 等语言开发应用时,基于角色的访问控制往往是框架的一部分,并可随时使用。 但是,当将应用作为一个大得多的系统的一部分进行开发时,这并没有什么帮助,因为整个系统不会自始至终使用相同的框架。
我们开始研究可行的方案,很快就发现我们有一个选择。 一种方法是使用集中式服务,如 Keycloak,它将充当所有微服务的通用授权代理。 它有一个明显的缺点,即集中式代理会成为单一故障点和潜在的瓶颈。 这里的任何故障都可能意味着分布式微服务架构的所有优势都会立即丧失。
因此,我们转而采用去中心化的方式,特别是将注意力转向寻找一种在不同语言中表示和处理访问控制列表的一致方式。于是,我们发现了 Casbin, 这个授权库完全可以做到这一点,并且可以用各种不同的语言来实现
我们有了 RBAC 实现,但还有一个障碍:我们需要的是 Ruby 实现,而 Casbin 尚未移植到 Ruby。 所以,我们决定自己动手实现,结果就是 Casbin-Ruby。 因为 Casbin 之前已经被移植到许多不同的语言中,所以它有一个全面的测试套件,我们可以用这个套件来验证我们的实现与其同类实现的行为是否一致。
工作原理
简而言之,每个微服务都可以访问分布在整个系统中的两个文件。 第一个文件包含用户、组、角色等的列表,换句话说,它定义了授权原则。 第二个文件包含主体之间的映射:实际上,它是系统使用的所有访问控制列表的合并。
这为我们面临的最核心的挑战提供了解决方案:用户、角色及其功能的去中心化(或分布式)管理。
Casbin 可以实现以下功能:
- 以经典的
{subject, object, action}
形式或您定义的自定义形式强制执行策略,两种形式均支持允许授权和拒绝授权。 - 处理访问控制模型及其策略的存储。
- “管理角色-用户”映射和“角色-角色”映射(也称为 RBAC 中的角色层次结构)。
- 支持内置超级用户,如
root
或administrator
. 超级用户可以在没有明确权限的情况下执行任何操作。 - 支持规则匹配的多个内置运算符。 例如,
keyMatch
can map a resource key/foo/bar
可以将资源键/foo*
模式。
Casbin 无法实现以下功能:
- 身份验证(即,在用户登录时验证用户名和密码)
- 管理用户或角色列表。 让项目本身来管理这些实体更加方便。 用户通常都有自己的密码,而 Casbin 并不是作为密码容器来设计的。 然而,Casbin 会为 RBAC 方案存储“用户-角色”映射。
请使用以下代码安装 Casbin:
to use latest version:
gem 'casbin-ruby', github: 'CasbinRuby/casbin-ruby'
to use specific version:
gem 'casbin-ruby', '1.0.5'
未来开发计划
开发 Casbin 的 Ruby 实现,我们差不多用了一个月的时间,通过测试来自不同语言的现有实现,我们一开始就具有深入的测试覆盖率基础,并在整个过程中沿用了 TDD 优先(测试驱动开发)的方式。
自从开发了核心 Ruby 实现后,我们就开始着手编写存储和通知。 我们还计划支持角色管理器,还打算为不同的 Ruby 框架添加桥,例如 Ruby on Rails、 Hanami, 和 Roda.
您可以在 Github 上找到 Casbin-Ruby,还可以在其网站上了解有关 Casbin 本身的更多信息。