Route.Allow 或 Plugin.Allow。
访问层
前三层由内核配置。最后一层由插件在注册其资源时声明。
用户身份
对于 HTTP 请求,内核首先检查arupa-auth 会话 cookie,
然后检查 Authorization 标头。有效的会话会解析为一个用户名。
内核在 Groups 中查找该用户名,并创建一个主机验证的身份,其中包含:
- 用户名;
- 包含该用户名的组;以及
Authenticated状态。
Authorization 标头执行相同的身份验证解析。
策略语义
所有访问检查都使用相同的策略模型:- 空策略为公开策略,允许未经身份验证的用户访问。
RequireAuth = true且未指定任何组名,允许任何已验证的用户访问。- 非空的
Groups列表要求用户进行身份验证,并且至少属于一个列出的组。 - 已验证但未属于任何列出的组的用户将被禁止访问。
Groups = ["root", "staff"]
允许 root 或 staff 组的用户访问;用户无需同时属于这两个组。
两种拒绝状态不同:
- 未经身份验证的请求是身份验证失败,返回
401 Unauthorized。 - 已验证但未满足组要求的用户是授权失败,返回
403 Forbidden。
主机路由访问
Route.Allow 在请求到达主机处理程序或插件处理程序之前保护 HTTP 路径:
Route.Allow 映射使用内核的共享路径模式实现。普通路径是精确匹配,而以 / 结尾的模式匹配该路径的子树。/* 不是有效的配置;它不支持通配符。
当多个 Route.Allow 模式匹配时,匹配长度最长的模式生效。
内核不会合并来自多个匹配模式的组。请参阅
路由 以了解完整的路径模式规则、
根路径行为和验证详情。
如果没有匹配的规则,Route.Allow 不会限制请求。
如果匹配的规则的组列表为空,则其策略实际上也是公开的,
因为空的访问策略允许所有人访问;空列表并不意味着“拒绝所有请求”。
外部身份验证中间件会对每个 HTTP 请求评估 Route.Allow。
当它拒绝请求时,会返回标准的 JSON 401 或 403 响应。
它不使用已配置的 Pages 重定向。
请参阅 页面以了解插件保护资源使用的浏览器重定向。
插件级访问权限
[Plugins.<name>] 下的 Allow 策略适用于整个插件:
- 插件的 HTTP 路由;
- 插件的静态文件挂载;
- 连接到插件的 Socket.IO 命名空间;以及
- 在这些命名空间中接收到的事件。
Allow 列表表示插件在此层保持开放状态。
非空列表要求用户至少属于列出的组之一。
[Plugins.default] 提供插件的基本配置。
[Plugins.<name>] 中的非空 Allow 列表会替换该插件的默认组列表。
如果每个插件的列表被省略或为空,则当前实现将保留默认列表。
当内核重新加载其配置时,插件策略也会刷新,
因此加载插件会使用更新后的组列表来处理后续的请求和事件。
插件资源访问
插件在注册资源时可以添加其他策略。 这些策略并非写在config.toml 文件中;它们是插件注册协议的一部分。
HTTP 路由和静态挂载点各自拥有自己的 Access 策略。
内核首先检查插件级别的策略,然后检查资源级别的策略:
Plugin.Allow 中的 staff 组和 Access.Groups 中的 operators 组才能访问该路由。
示例
使用以下配置:admin 用户可以访问 /api/plugins 主机路由规则,因为他们属于 root 组。alice 已通过身份验证,但访问该路径时会收到 403 Forbidden 错误,因为他们不属于 root 组。未经身份验证的请求会收到 401 Unauthorized 错误。
同一个 admin 用户无法访问任何受 hello 插件的 Allow = ["staff"] 保护的资源。
因为 admin 不在 staff 组中。当策略指定了用户组时,仅通过身份验证是不够的。