将访问权限存储在数据库表中是否常见?

时间:2017-10-24 20:51:35

标签: java rest authorization jax-rs access-control

问题

对于基于角色的RESTful API访问,将访问权限存储在数据库表中是否常见(并且被认为是安全的)?我正在讨论用于限制用户访问某些端点,HTTP方法(GET,POST,PUT,DELETE)或限制查询中接受/返回哪些字段的访问权限。

或者访问权限通常会存储在应用程序代码中(即编译到API本身的基于角色的逻辑)?更一般地说,处理RESTful API的自定义访问权限的推荐方法是什么?

我没有在API本身上引用用户身份验证或基于OAuth的授权,这将通过基于标准令牌的机制进行处理。

背景

我们在Java EE 7中构建RESTful API,其中包括基于角色的访问控制机制,以确定在查询中接受/返回的端点,HTTP方法和字段。在我们的初始设计中,我们使用端点方法Container Request Filter读取的自定义注释来根据用户的角色确定用户的权限,我们使用JsonView来过滤特定的实体字段(德)的序列化。

这个系统有效,但我们觉得它过于复杂,难以维护。我们已经讨论过将此授权信息移动到几个数据库表,最重要的是存储表和列访问权限(PK和FK列摘录)。

   AccessPermissions
========================
|  Column    |  Type   |
========================
| TableName  | varchar |
| ColumnName | varchar |
| HasCreate  | bit     |
| HasRead    | bit     |
| HasUpdate  | bit     |
| HasDelete  | bit     |

每个角色(表未显示)都会在此AccessPermissions表中引用可能的许多行,以便可以通过询问用户是否具有查询表的条目来实现端点方法访问和(反)序列化。允许所请求访问的列名。

例如,带有POST /endpoint1的{​​{1}}会要求为用户分配一个角色,该角色在{"field1": "value", "field2": 23} AccessPermissionsTableName = 'endpoint1'中有任何行,并且请求正文中的JSON将仅对所述行中的命名列进行反序列化。因此,如果对应于此用户角色的HasCreate = true中的唯一行是AccessPermissions,那么('endpoint1', 'field1', true, false, false, false)将被允许,但JSON正文的一部分将不会反序列化(即{ {1}})。 (此外,此用户可以POST但不能field2。)

1 个答案:

答案 0 :(得分:0)

通常,您希望尽可能多地将功能分离。就像您不会紧密地(或重新实现)身份验证或在API /应用程序代码中记录一样,您希望保持授权解耦。

实际上有一个名称:外部授权。 Gartner称其为外部授权管理(EAM)。有几种方法可以实现这一目标。首先,您的开发框架可能为您提供了一种在API上定义授权的方法。 Spring Security,.NET声明就是这样的例子。

最重要的是,您有授权模型:

  • RBAC(基于角色的访问控制):在RBAC中,您拥有分配给资源的用户,角色和权限(有时称为权利)。例如,您可能有用户Alice和角色管理员。该角色管理器将viewEndPoint1作为权限。在某种程度上它与你的建议非常相似。您的REST框架应该能够为您提供工具来实现此目的,例如通过注释。有一篇很好的文章,你可以read up here
  • ABAC(基于属性的访问控制):在ABAC中,您完全外部化了应用程序的授权。这就是我每天都在做的事情,所以我可能有点偏颇。在ABAC中,您有策略决策点(PDP)和策略执行点(PEP)的概念。后者是位于API前面的拦截器/ API网关/代理。 PEP拦截所有进出的流量,并询问PDP呼叫是否被授权。 PDP配置有一组基于属性的策略,用于说明可以和不可以发生的事情。这使您可以使用基于策略的细粒度授权方法。您不再需要再创建自定义RBAC数据库架构。

想象一下,您的API是关于保险合同和索赔的:

  • / ACME /收缩
  • / ACME /合同/ {contractId}
  • / ACME /权利要求
  • / ACME /权利要求/ {ClaimID的}
  • / ACME /客户
  • / ACME /客户/ {CUSTID} /合同
  • / ACME /客户/ {CUSTID} /权利要求

依此类推......你的政策可以说明:

  • 保险销售代表可以查看与其相关的客户的合同。
  • 索赔处理者可以编辑其所在地区的客户声明
  • 客户可以查看他们的所有合同和索赔。
  • 客户可以查看他们作为监护人的另一位客户的合同。

如您所见,该策略定义了高级权利。这些来自您的业务应用程序的元数据(您已经拥有),例如合同ID,合同价值,合同区域,合同客户;索赔ID,索赔区域;客户指定销售代表...

有几个框架可以实现这种方法。我工作最多的是XACML(可扩展访问控制标记语言)。

它为您的API安全带来的一些主要好处是:

  • 细粒度访问:您可以使用风险,上下文和关系
  • 完全脱离app逻辑 - 摆脱自定义代码和db模式
  • 可扩展:您可以在需要时添加新方案。因此,如果您将来有新API,则只需添加新策略即可。
  • 可审计性&问责制:您可以比编码更容易审计政策;您可以证明谁(试图)访问(编辑)API以及该访问是被授予还是被拒绝
  • 过滤:您可以过滤返回的数据

看看这个report on API security免责声明:我为写这篇文章的公司工作)。