【问题标题】:RESTful API authorization on entities/resources?实体/资源的 RESTful API 授权?
【发布时间】:2014-08-29 17:33:50
【问题描述】:

我正在开发具有非常复杂的访问控制规则的系统中的 API。通常需要复杂的 SQL 查询来确定用户是否具有对特定资源的读取或写入访问权限。这会在我们的客户端应用程序中造成很多复杂性和冗余,因为它们必须了解所有这些规则才能确定是否向用户提供每个对象的 CRUD 选项。

我的目标是减少客户端的大部分复杂性,并在 API 中容纳所有复杂的逻辑。这样,针对我们的 API 编写的新客户端应用程序可以避免在确保 UI 仅向用户提供有效选项时重新实现复杂的访问规则逻辑。

我不确定处理此问题的最佳方法是什么。我正在考虑两种不同的选择,但我不知道是否有更好或更标准的方式向 API 的调用者公开通用访问信息。

选项 1

当调用者对资源实体或它们的集合发出 GET 请求时,每个返回的实体都将返回一个附加的 _allowed_actions 字段,这是一个允许调用者对该实体执行的操作的数组。例如,请求Listing 对象可能会导致以下响应。

GET /listing/5

{
 "id": 5,
 "address": "123 Foo Street",
 "city": "New York",
 "state": "New York",
 "price": 457000,
 "status": "pending",
 "_allowed_actions": ["READ", "UPDATE", "DELETE"]
}

仍然不确定如何与客户联系,他们是否有权使用此方法创建资源实体的实例,但也许客户只需要对权限结构保持足够的了解即可自行确定。与创建实例相关的访问规则通常不如 READ/UPDATE/DELETE 访问规则复杂,因此这似乎并不算太​​糟糕。

选项 2

创建一个元 API,客户端可以向该 API 发出请求,以确定他们可以对每个资源执行哪些操作。例如,检查客户可以对列表做什么:

GET /access-query/listing/5

{
 "allowed_actions": ["READ", "UPDATE","DELETE"]
}

并检查列表允许的一般选项,包括 CREATE:

GET /access-query/listing

{
 "allowed_actions": ["READ", "CREATE", "UPDATE", "DELETE"]
}

这种方法的好处是,它允许调用者全面了解他们可以以通用方式对每个资源执行什么操作。这样,客户就不必了解创建列表需要“create_listing”权限和非试用用户状态。他们可以简单地提前查询这些信息。

这种方法的缺点是它增加了请求的数量。与其要求客户了解权限逻辑,他们现在必须查询一次以确定他们可以做什么,然后再查询一次。

我对这两种方法都不是特别在意,但目前我能想到的只有它们。有没有更好的方法来解决这个问题?

【问题讨论】:

    标签: api rest authorization acl


    【解决方案1】:

    您正在寻找的是细粒度的、外部化的授权:

    • 细粒度:您希望创建考虑多个参数或属性以及客户端(请求者)和目标实体之间可能的关系的授权策略,例如您的案例中的列表。
    • externalized:您希望将业务逻辑与授权逻辑解耦。在您的问题中,您抱怨代码和 SQL 语句变得多么复杂。这是没有明确区分业务逻辑和授权逻辑的直接后果。

    有一个称为基于属性的访问控制 (ABAC) 的模型,它定义了一种细粒度外部授权的方法。美国国家标准与技术研究院 NIST 制作了一个report on ABAC,您可以在线阅读。

    促进结构化信息标准的组织 OASIS 定义了一个名为 XACML(可扩展访问控制标记语言)的标准来实施 ABAC。

    XACML 为您带来:

    • 如下图所示的架构
      • 策略执行点 (PEP) 拦截您的 API 调用。它保护您的 API、检查消息并向策略决策点 (PDP) 发送授权请求。
      • 策略决策点 (PDP) 根据一组用 XACML 编写的授权策略评估来自 PEP 的传入授权请求。 PDP 最终会做出允许或拒绝的决定。为了做出决策,它可能需要从数据库、Web 服务、LDAP 或文件中查找其他属性值。这些在架构中被称为策略信息点。
    • 一种策略语言:XACML 策略语言是基于属性的,这意味着它使用属性来定义什么可以被允许,什么不能。例如,您可以定义如下规则:
      • 当且仅当列表位置 == 代理位置时,房地产经纪人才能查看所有列表
      • 当且仅当房地产经纪人拥有房源时,他/她才能编辑房源
      • 当且仅当列表中的项目已售出并且当且仅当代理是出售该项目的人时,房地产经纪人才能关闭列表。
    • 请求/响应方案:XACML 还定义了一种查询 PDP 并获取响应的方法。可以通过单个问题或通过单个请求中的多个问题来查询 PDP,例如:
      • Alice 可以查看清单 123 吗?是的,允许。
      • Alice 可以查看、编辑或删除列表 123 吗?允许;否定;拒绝。

    使用基于 XACML 的方法,您可以将业务逻辑和 API 与授权逻辑分开。这有几个好处:

    1. 您始终可以重新实现 API 并保持相同的授权模型
    2. 无需重写授权即可轻松扩展 API
    3. 您可以独立于代码更改授权逻辑
    4. 您可以更轻松地审核您的授权逻辑
    5. 您的授权逻辑是技术中立的。它适用于 REST API、网络服务、数据库等

    我建议您查看以下资源:

    1. OASIS XACML website
    2. ALFA plugin for Eclipse - 用于编写 XACML 策略的免费工具。
    3. XACML developer community

    XACML 有供应商实现和开源实现:

    • Axiomatics 是一个供应商解决方案,提供 .NET 和 Java XACML 实现
    • SunXACML 是一个长期存在的开源 Java XACML 实现

    HTH, 大卫。

    【讨论】:

      【解决方案2】:

      不是想复活一个老问题,但我来这里是为了寻找几乎完全相同的东西,并想添加一个我认为更 RESTful 的解决方案。

      我实际上并没有实现这个,但认为它可以帮助其他来到这里的人......

      您的第二个选项几乎是我认为应该做的,但不是 get 使用 OPTIONS 动词到您的资源,然后将返回一个“允许”标题,其中包含该资源的可用动词列表。

      选项 /listing/5

      假设你的资源足够细粒度到可以理解,那么你就会知道你是否可以进行 POST/DELETE

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多