实体/资源上的RESTful API授权?

wil*_*iam 3 api rest acl authorization

我正在使用具有非常复杂的访问控制规则的系统中的API.通常,需要复杂的SQL查询来确定用户是否具有对特定资源的读取或写入访问权限.这会在我们的客户端应用程序中造成很多复杂性和冗余,因为他们必须知道所有这些规则,以确定是否为每个对象呈现用户CRUD选项.

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

我不确定最好的办法是什么.我正在考虑两种不同的选择,但我不知道是否有更好或更标准的方法向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"]
}
Run Code Online (Sandbox Code Playgroud)

仍然不确定如何与客户关联他们是否有权使用此方法创建资源实体的实例,但客户可能只需要保持对权限结构的充分理解以自行确定.围绕创建实例的访问规则通常不如READ/UPDATE/DELETE访问规则复杂,因此看起来并不太糟糕.

选项2

创建一个元API,客户端可以向其发出请求,以确定它们可以对每个资源执行哪些操作.例如,检查客户端可以对列表执行的操作:

GET/access-query/listing/5

{
 "allowed_actions": ["READ", "UPDATE","DELETE"]
}
Run Code Online (Sandbox Code Playgroud)

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

GET/access-query/listing

{
 "allowed_actions": ["READ", "CREATE", "UPDATE", "DELETE"]
}
Run Code Online (Sandbox Code Playgroud)

这种方法的好处是它允许呼叫者以通用方式完全理解他们可以对每个资源做什么.这样,客户端就不必理解为了创建列表,需要"create_listing"权限和非试用用户状态.他们可以提前查询此信息.

这种方法的缺点是它增加了请求量.他们现在必须查询一次以确定他们可以做什么以及第二次执行此操作,而不是要求客户端了解权限逻辑.

我并不特别关心这些方法中的任何一种,但我现在只能提出这些方法.有没有更好的方法来解决这个问题?

Dav*_*ard 8

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

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

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

OASIS是推进结构化信息标准的组织,它定义了一个名为XACML(可扩展访问控制标记语言)的标准来实现ABAC.

XACML为您带来:

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

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

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

我建议您查看以下资源:

  1. OASIS XACML网站
  2. EclipseALFA插件 - 一个编写XACML策略的免费工具.
  3. XACML开发者社区

XACML有供应商和开源实现:

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

HTH,大卫.


小智 5

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

我实际上还没有实现这一点,但认为它可能会帮助来到这里的其他人......

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

选项/列表/5

假设您的资源足够细粒度,这有意义,那么您就会知道是否可以进行 POST/DELETE