带有过滤和授权的RESTFul API端点设计

Joh*_*yal 4 rest authorization uri endpoints

我正在与具有不同权限的使用者一起设计REST API。我知道资源的表示形式不应根据用户而改变。因此,我试图确定哪种方法是最好的:

GET-列出所有文档的集合-仅限管理员。

/ api / documents

GET-所有文档的列表集合-有权访问文档123的任何用户

/ api / documents / 123

因此,对于普通用户,端点应为

列出用户12的所有文档

/ api / user / 12 / documents

假设用户12具有访问权限的文档123

/ api / documents / 123

或...端点应如下所示,并使用查询字符串过滤器:

/ api / documents?user = 12

/ api / documents / 123

Dav*_*ard 6

我会将业务逻辑和授权逻辑完全分开。如果要检索文档 XYZ,则不会将用户 ID 作为 HTTP 参数传递。

你建议/api/documents?user=12但实际上它应该只是/api/documents. 用户信息应该来自认证层。

同样,授权应该是完全独立的。原因如下:

  • 关注点分离
  • 能够独立于业务逻辑更新授权逻辑
  • 避免影响 API 设计

API 应该只反映您关心的那些业务对象,例如在这种情况下的文档(如果您希望显示用户配置文件,也可能是用户...)。

要处理身份验证,请使用容器的标准技术(例如 HTTP 基本身份验证)或通过专用框架使用高级身份验证技术 (OAuth..)。

要处理授权,请使用过滤器、拦截器。在 Java 世界(其中 JAX-RS 实现 REST),看看 Jersey拦截器和过滤器。然后,您希望拦截器(或策略执行点 - PEP)查询外部授权服务(或策略决策点)。

保护 REST API - 架构

进一步了解ABAC(基于属性的访问控制模型)和XACML(可扩展访问控制标记语言),它们解释了如何在不混合业务逻辑和授权逻辑的情况下控制对 REST API 的访问。


Eri*_*ein 5

在这种情况下,您只能使用两个端点(和一个标头!)。确保用于的API /documents返回Vary: Authorization标头。那你可以用

GET /api/documents              // return all docs the logged-in user can see
GET /api/documents?userId=bob   // return all of bob's docs that the logged-in user can see
GET /api/documents/123          // return doc 123 if the logged-in user can see it    
Run Code Online (Sandbox Code Playgroud)

嵌套用户la并不是完全不合理的GET /api/users/bob/documents。我发现对于最终用户而言,要学习具有大量端点的API更加困难,而且我认为嵌套方法倾向于创建许多端点。从概念上讲,去/documents看看可以过滤的内容要容易得多,而不是查看每个终结点并查看具有哪些过滤器。