编号 | 211 |
---|---|
原文链接 | AIP-211: Authorization checks |
状态 | 批准 |
创建日期 | 2021-02-24 |
更新日期 | 2021-02-24 |
大多数操作,无论读或写,都需要授权:获得执行用户请求的操作的权限。此外,向 未授权 用户提供了多少信息也非常重要,因为信息泄露也是安全问题。
指南
服务 必须 在验证请求之前检查授权,确保API界面的安全性和一致的用户体验。一个操作 可以 需要多个权限或前提条件才获得授权。
如果请求因某种原因无法通过授权检查,服务 必须 返回 PERMISSION_DENIED
错误,相应的错误信息 应当 类似于:“权限 {p}
在资源 {r}
上被拒绝(资源可能不存在)。”这避免了泄露资源是否存的信息。
如果由于资源不存在而无法确定授权,服务 应当 检查在上级资源上读取下级资源的授权。如果通过授权检查,返回 NOT_FOUND
。
多重操作
服务可能遇到这种情况:有两个操作分别需要不同的权限,执行任何一个操作都会暴露资源的存在性,而用户只拥有其中一个操作的权限。
此时,服务 应当 只检查与被调用操作有关的授权, 不应 尝试“帮助”检查其他权限。这可能暴露资源的存在,这样的算法难以实现,很容易意外泄露信息。
假设有以下场景:
- 用户无法访问集合中的某个资源。
- 用户 确实 有权限在集合中创建资源,并且集合允许用户设定资源标识(这意味着标识冲突引发的资源创建失败暴露了资源的存在)。
此时,获取或创建方法 应当 只检查和 自身 有关的权限,确定返回哪个错误,而非检查对方的权限。
理由
RFC 7231 §6.5.3指出,不希望暴露资源存在性的情况下,服务可以使用 404 Not Found
代替 403 Forbidden
。本AIP主张使用 PERMISSION_DENIED
(对应于HTTP的 403 Forbidden
)。我们采取这一立场的理由如下:
- “在没有授权的时候用
404 Not Found
替代403 Forbidden
”的做法违反直觉,增加了故障排查难度。- 服务 可以 返回关于缺少授权的信息,缓解这个问题,同时仍使用
404 Not Found
状态码。但这传递了混淆的信息。
- 服务 可以 返回关于缺少授权的信息,缓解这个问题,同时仍使用
- 虽然
403 Forbidden
本质上是需要手动处理的错误,而404 Not Found
通常是应用程序可以处理的有效应答(例如“获取或创建”)。将其作为权限错误剥夺了应用程序的优势。 - RFC 7231 §6.5.4指出客户端可以缓存
404 Not Found
结果,但权限错误通常不能缓存。根据条件主动发送缓存控制指令可以缓解问题,但违背了缓存机制的目的。 - 这里的指南与大部分现实世界的授权系统更加接近。
修订记录
- 2021-05-11 添加更详细的“理由”部分。