跳转到主要内容
Arupa 分层评估访问权限。内核首先解析请求用户的身份, 然后应用保护主机路径、插件和特定插件资源的策略。 应用于请求的每一层都必须允许该请求。 更具体的策略不会覆盖更广泛的限制,插件也不能使用其自身的资源策略来绕过 Route.AllowPlugin.Allow

访问层

前三层由内核配置。最后一层由插件在注册其资源时声明。

用户身份

对于 HTTP 请求,内核首先检查 arupa-auth 会话 cookie, 然后检查 Authorization 标头。有效的会话会解析为一个用户名。 内核在 Groups 中查找该用户名,并创建一个主机验证的身份,其中包含:
  • 用户名;
  • 包含该用户名的组;以及
  • Authenticated 状态。
无效或缺失的会话会产生未认证的身份。内核不会为未认证的请求向插件发送用户对象。 Socket.IO 在握手过程中使用会话 cookie 或 Authorization 标头执行相同的身份验证解析。

策略语义

所有访问检查都使用相同的策略模型:
结果按如下方式确定:
  • 空策略为公开策略,允许未经身份验证的用户访问。
  • RequireAuth = true 且未指定任何组名,允许任何已验证的用户访问。
  • 非空的 Groups 列表要求用户进行身份验证,并且至少属于一个列出的组。
  • 已验证但未属于任何列出的组的用户将被禁止访问。
组列表是一个“或”列表。例如,Groups = ["root", "staff"] 允许 rootstaff 组的用户访问;用户无需同时属于这两个组。 两种拒绝状态不同:
  • 未经身份验证的请求是身份验证失败,返回 401 Unauthorized
  • 已验证但未满足组要求的用户是授权失败,返回 403 Forbidden

主机路由访问

Route.Allow 在请求到达主机处理程序或插件处理程序之前保护 HTTP 路径:
映射值是一个组列表。当已验证的用户属于列表中的至少一个组时,请求才被允许。 Route.Allow 映射使用内核的共享路径模式实现。普通路径是精确匹配,而以 / 结尾的模式匹配该路径的子树。/* 不是有效的配置;它不支持通配符。 当多个 Route.Allow 模式匹配时,匹配长度最长的模式生效。 内核不会合并来自多个匹配模式的组。请参阅 路由 以了解完整的路径模式规则、 根路径行为和验证详情。 如果没有匹配的规则,Route.Allow 不会限制请求。 如果匹配的规则的组列表为空,则其策略实际上也是公开的, 因为空的访问策略允许所有人访问;空列表并不意味着“拒绝所有请求”。 外部身份验证中间件会对每个 HTTP 请求评估 Route.Allow。 当它拒绝请求时,会返回标准的 JSON 401403 响应。 它不使用已配置的 Pages 重定向。 请参阅 页面以了解插件保护资源使用的浏览器重定向。

插件级访问权限

[Plugins.<name>] 下的 Allow 策略适用于整个插件:
此策略会在请求或事件到达插件拥有的任何资源之前进行检查。 它适用于:
  • 插件的 HTTP 路由;
  • 插件的静态文件挂载;
  • 连接到插件的 Socket.IO 命名空间;以及
  • 在这些命名空间中接收到的事件。
空的 Allow 列表表示插件在此层保持开放状态。 非空列表要求用户至少属于列出的组之一。 [Plugins.default] 提供插件的基本配置。 [Plugins.<name>] 中的非空 Allow 列表会替换该插件的默认组列表。 如果每个插件的列表被省略或为空,则当前实现将保留默认列表。 当内核重新加载其配置时,插件策略也会刷新, 因此加载插件会使用更新后的组列表来处理后续的请求和事件。

插件资源访问

插件在注册资源时可以添加其他策略。 这些策略并非写在 config.toml 文件中;它们是插件注册协议的一部分。 HTTP 路由和静态挂载点各自拥有自己的 Access 策略。 内核首先检查插件级别的策略,然后检查资源级别的策略:
对于 Socket.IO,检查分两个级别进行:
事件策略是可选的。如果命名空间没有为某个事件定义策略, 则命名空间策略仍然适用,但不会进行额外的事件检查。 插件未声明的事件将被忽略。 由于每个检查都必须通过,因此有效权限是适用层级的交集。 例如,用户必须同时属于路由的 Plugin.Allow 中的 staff 组和 Access.Groups 中的 operators 组才能访问该路由。

示例

使用以下配置:
admin 用户可以访问 /api/plugins 主机路由规则,因为他们属于 root 组。alice 已通过身份验证,但访问该路径时会收到 403 Forbidden 错误,因为他们不属于 root 组。未经身份验证的请求会收到 401 Unauthorized 错误。 同一个 admin 用户无法访问任何受 hello 插件的 Allow = ["staff"] 保护的资源。 因为 admin 不在 staff 组中。当策略指定了用户组时,仅通过身份验证是不够的。