【问题标题】:RESTFul API endpoint design with filtering and authorization带有过滤和授权的 RESTFul API 端点设计
【发布时间】:2014-08-09 19:08:09
【问题描述】:

我正在设计一个具有不同权限的消费者的 REST API。我知道资源的表示不应该根据用户而改变。因此,我正在尝试确定哪种方法最好:

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

/api/文档

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

/api/documents/123

因此对于普通用户来说,端点应该是

列出用户 12 的所有文档

/api/user/12/文档

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

/api/documents/123

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

/api/documents?user=12

/api/documents/123

【问题讨论】:

    标签: rest authorization uri endpoints


    【解决方案1】:

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

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

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

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

    API 应该只反映您关心的那些业务对象,例如在这种情况下的文档(如果您希望显示用户个人资料,可能还有用户...)。

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

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

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

    【讨论】:

      【解决方案2】:

      在这种情况下,您可以只使用两个端点(和一个标头!)。确保 /documents 的 API 返回 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    
      

      将用户嵌套为GET /api/users/bob/documents 并非完全不合理。我发现最终用户更难学习具有大量端点的 API,而且我觉得嵌套方法往往会创建许多端点。从概念上讲,转到/documents 并查看您可以过滤的内容比查看每个端点并查看它具有哪些过滤器更容易。

      【讨论】:

      • 谢谢 - 虽然我的理解是给定的端点应该总是返回相同的结果,无论权限如何。所以。 GET /api/documents 无论如何都会返回所有文档。如果角色更有限的用户访问它,那么他们应该得到 403 并使用不同的端点。
      • @JohnRoyal 这就是 Vary: Authorization 标头的目的。它让任何相关方都知道结果将根据用户的凭据而有所不同。端点与用户无关,这很好,但并不总是实用。当然 HTTP 的设计并没有将其作为预期的限制,否则就不会有 Vary: Authorization 标头!
      • @JohnRoyal 如果我在没有写入权限的情况下尝试 PUT 到 /documents/123 怎么办?我可以阅读但不能修改它。但是,作者可以 GET 和 PUT 到该文档。相同的URI,不同的用户拨打相同的电话,结果不同。我看不出这种情况和 GET 基于身份验证返回不同结果之间的根本区别。
      • 我现在明白了。谢谢
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多