概念、想法、策略
概念、想法、策略通过访问控制实现授权

通过访问控制实现授权

授权是将 Web 应用程序的各个部分和资产的访问权限授予用户的过程。授权用户的常见方式是通过访问控制,即网站管理员定义用户和其他实体需要获得哪些权限才能访问哪些资源。

授权不应与身份验证相混淆。身份验证是验证用户确实是其所声称身份的过程,通常通过提供账户凭据来完成。用户通过身份验证后,仍需在每次请求时执行授权过程,以确保用户有权访问所请求的资源。

通过 GraphQL 访问应用程序时,我们必须验证用户是否有权访问 schema 中请求的元素。授权逻辑是否应该编写在 GraphQL 层内?

答案是否定的。正如 graphql.org 的文档 所明确指出的,授权逻辑属于业务逻辑层,GraphQL 从该层访问授权逻辑。这样,应用程序可以拥有单一的授权信息来源(即 WordPress 所提供的):

应用程序图

Gato GraphQL 遵循这一原则,反映(并在引擎底层委托给)WordPress 提供的授权机制。

访问控制策略

在可以为应用程序实现的多种访问控制策略中,最流行的两种是基于角色的访问控制(RBAC)和基于属性的访问控制(ABAC)。

WordPress 和 Gato GraphQL 均支持这两种策略。

基于角色的访问控制根据角色授予权限,然后将角色分配给用户。例如,WordPress 拥有可访问所有资源的 administrator 角色,以及具有不同程度受限权限的 editorauthorcontributorsubscriber 角色,例如可以创建并发布博客文章、仅创建,或仅阅读。

基于属性的访问控制根据可分配给不同实体(包括用户、资产和环境条件,如访问时间或访客 IP)的元数据来授予权限。例如在 WordPress 中,edit_others_posts 能力用于验证用户是否可以编辑其他用户的文章。

总体而言,ABAC 优于 RBAC,因为它允许我们以细粒度控制配置权限,且权限的目的明确无歧义。

例如在 WordPress 中,editor 角色拥有 edit_others_posts 能力,但我们可能希望允许具有 author 角色的人编辑另一位作者的文章,同时又不授予编辑者所拥有的全部权限集合(例如删除其他作者文章的权限)。因此,授予 edit_others_posts 能力并检查此条件,比检查 editor 角色更为合适。

定义可见性

当用户没有权限访问 GraphQL schema 中所请求的字段时,返回的错误应该是什么?

根据 schema 所需的可见性,有两种可能性:公开或私有。

对于公开 schema,所有用户看到的 GraphQL schema 是相同的,每个字段都描述了访问该字段所需的权限。当请求无法访问的字段时,错误消息将说明用户为何未被授予访问权限。

公开 schema:当字段访问失败时,错误消息说明原因

对于私有 schema,GraphQL schema 针对每个用户进行定制,仅公开该用户可以访问的字段。当请求无法访问的字段时,错误消息将显示该字段不存在。

私有 schema:该字段在 schema 中不存在

通过用户界面进行访问控制

在 Gato GraphQL 中,访问控制规则在运行时作为通过访问控制列表进行的用户自定义配置注入到 schema 中。这样,GraphQL 层无需更新任何代码或重新编译 schema,即可立即反映访问控制策略的变更:

通过用户界面进行访问控制

网站管理员配置 ACL,选择以下内容:

  • 要验证的字段
  • 从以下选项中选择验证规则:
    • 用户是否必须已登录?
    • 用户是否必须已登出?
    • 用户是否必须拥有特定角色?
    • 用户是否必须拥有特定能力?
  • 规则特定配置:
    • 哪些角色?
    • 哪些能力?
  • 可见性:
    • 默认(即与 schema 分配的相同)?
    • 公开?
    • 私有?

配置访问控制列表