简体中文
  • ciam
  • auth
  • authorization

CIAM 102:授权与基于角色的访问控制

组织和租户非常适于对身份进行分组,但它们导致了一种绝对的民主:在这个系统中,每个人都可以做任何事情。虽然乌托邦仍然是一个谜,让我们看一下访问的治理:授权(AuthZ)。

Gao
Gao
Founder

背景

前一篇文章中,我们介绍了认证(AuthN)和授权(AuthZ)的概念,以及一些令人头痛的术语:身份,组织,租户等。

组织和租户非常适合对身份进行分组,但它们通向绝对的民主:在这个系统中,每个人都可以做任何事情。虽然乌托邦仍是一个谜,让我们看一下访问的治理:授权(AuthZ)。

为什么我们需要授权?

Notion 是一个很好的例子。对于你拥有的每一个页面,你可以选择让它私有,只有你可以访问,或者与朋友分享,甚至公开。

或者,对于一个在线书店,你希望每个人都能看到所有的书,但是客户只看他们自己的订单,和卖家只管理他们商店里的书。

AuthZ 和 AuthN 是复杂业务模型的必要组成部分。它们通常并肩作战;AuthZ 验证用户的访问,而 AuthN 对身份进行认证。两者对于一个安全的系统都是必要的。

基本的授权模型

这是最常见的 AuthZ 模型之一:如果身份资源执行动作,那么接受被拒

在 Notion 的例子中,模型是个人页面执行查看

如果页面是私有的:

  • 当你对你的页面执行查看时,你将收到接受
  • 所有其他人当对你的页面执行查看时,应该收到被拒

基于共识,业界开发了各种授权技术,如基于角色的访问控制(RBAC),基于属性的访问控制(ABAC)。今天,我们将关注NIST RBAC 模型级别1:Flat RBAC。

基于角色的访问控制

让我们扩展书店的例子。假设我们有很多客户,但只有一个卖家:

  • 客户可以查看和订购书籍,以及查看他们自己的订单。
  • 卖家可以查看,创建和删除书籍,并管理客户订单。

定义资源

在 Logto 中,资源(即 API 资源)通常代表一组实体或项目,因为需要使用有效的 URL 作为指示器。因此我们定义了两个资源:

  • 书籍:https://api.bookstore.io/books
  • 订单:https://api.bookstore.io/orders

强制使用 URL 格式的一个优点是它可以映射到你 API 服务的实际地址,当与系统中的其他组件集成时,可以提高可读性和可识别性。

定义权限

由于我们引入了资源的概念,在 Logto 中,我们还强制要求权限必须属于资源,反之,资源可以拥有权限。

让我们为资源添加一些权限:

  • 书籍:readcreatedelete
  • 订单:readread:selfcreate:selfdelete

尽管没有权限名称的要求,我们有以下约定:

<action> 要求描述一个权限,:<target> 可以忽略描述一个通用目标,即对资源中的所有实体或项目。例如:

  • 书籍资源中的权限 read 表示读取任意书籍的动作。
  • 订单资源中的权限 create:self 表示创建属于当前用户的订单的动作。

定义角色

简单来说,一个角色就是一组权限。让我们创建两个角色 customerseller 并把权限分配给它们如下:

你可能注意到,权限和角色的赋予是多对多的关系。

把角色分配给用户

就像角色权限赋值一样,用户角色赋值也是一种多对多的关系。因此,你可以把多个角色分配给一个用户,一个角色可以分配给多个用户。

连接各个点

下面是 Logto 中的级别1 RBAC 模型的完整关系图:

在 RBAC 模型中,权限总是 "positive" ,意味着授权判断很简单:如果用户有权限,那么接受;否则,拒绝。

假设 Alice 有 seller 角色,Bob 和 Carol 有 customer 角色。我们首先用自然语言描述动作,然后把它们编译到标准的授权格式:IDENTITY performs ACTION on RESOURCE,最后给出结论。

  • Alice 想添加一本新书出售:
    • 用户 Alice 对资源 Books (https://api.bookstore.io/books)执行 create
    • 由于 Alice 根据他们的 seller 角色被赋予了 Books 的 create 权限,结果是 ✅ 接受
  • Alice 想查看所有订单以看看销售是否符合他们的期望:
    • 用户 Alice 在 Orders 资源(https://api.bookstore.io/orders)上执行 read
    • 由于 Alice 根据他们的 seller 角色被赋予了 Orders 的 read 权限,结果是 ✅ 接受
  • Bob 想浏览书籍列表,看看有没有他们想购买的书。
    • 用户 Bob 在 Books 资源(https://api.bookstore.io/books)上执行 read
    • 由于 Bob 根据他们的 custome 角色被赋予了 Books 的 read 权限,结果是 ✅ 接受
  • Bob 想查看 Carol 的订单。
    • 由于这是别人的订单,所以 Orders 的 read:self 权限在此不起作用。
    • 用户 Bob 对 Orders 资源(https://api.bookstore.io/order)执行 read
    • 由于 Bob 没有 Orders 的 read 权限,结果是 ❌ 拒绝

其他 RBAC 等级

NIST RBAC 模型有四个级别:

  • Flat RBAC
  • Hierarchical RBAC
  • Constrained RBAC
  • Symmetric RBAC

如果你对此感兴趣,可以查看论文获取详细信息。

Logto 现在有 Level 1 的实现,将根据社区反馈进行更高级别的进展。如果更高级别适合你的需求,不要犹豫,告诉我们!

实践中

除了理论,我们还有大量技术工作要完成,以期模型能按预期工作:

  • 客户端和 auth 服务器开发
  • RBAC 数据库设计
  • 在不同服务之间的验证
  • 安全和开放标准合规
  • 角色,权限,资源管理和赋值

不要恐慌。我们考虑到这一点,并为所有上述内容增加了开箱即用的支持。查看 🔐 RBAC 菜谱,学习如何在 Logto 中使用 RBAC。

结束语

RBAC 对于大部分情况是一个强大的访问管理模型,但没有银弹。我们仍然有一些问题:

  • 我需要高级别的 RBAC 吗?
  • RBAC 与其他授权模型相比如何?
  • 如何定义不同组织之间的授权模型?