微服务中的授权 - 如何使用ACL来处理域对象或实体级访问控制?

Luk*_*s S 12 security spring acl authorization microservices

我目前正在基于Java Spring Cloud构建基于微服务的系统.一些微服务使用PostgreSQL,其中一些使用MongoDB.REST和JMS用于通信.计划是使用SSO和OAuth2进行身份验证

我面临的挑战是必须在域对象/实体级别上进行授权.这意味着需要某种ACL(访问控制列表).这种体系结构的最佳实践是避免这样的事情,并且可能在每个微服务中的应用程序/服务层级别上具有粗粒度的安全性,但不幸的是,这是不可能的.

我的最终想法是使用Spring Security ACL并在所有微服务之间的共享数据库中使用ACL表.数据库只能由Spring基础结构或Spring api访问.数据库架构看起来稳定,不太可能发生变化.在这种情况下,我只是打破了关于在微服务之间共享数据库的规则.

我正在考虑不同类型的分布式解决方案但留下了它们:

  • 一个带有ACL的微服务并使用rest访问它 - 问题是http调用太多,性能下降.我必须扩展Spring Security ACL以通过rest调用替换db访问
  • 每个微服务中的ACL都有自己的实体 - 听起来很合理,但想象一下,有一些实体的读取模型与某些其他微服务或同一实体同步,存在于不同的有界上下文(不同的微服务)中.ACL可能变得非常难以管理并且可能是错误的来源.
  • 一个带有ACL表的微服务,它与其他微服务同步作为读模型.问题是MongoDB的Spring Security ACL中没有支持.我在github上看到了一些自定义解决方案,是的,它是可行的.但是......在创建新实体时,我必须在拥有ACL的微服务中创建记录,然后将其作为读取模型异步同步到拥有该实体的微服务.它听起来不是一个简单的解决方案
  • 在API网关上选择一些基于URL的访问控制.但我必须以某种方式修改Spring Security ACL.API网关必须对其他服务了解太多.访问控制的粒度与REST api粒度绑定.也许我无法想象这种方法带来的所有后果和其他问题
  • 最后,我提到的共享数据库的解决方案是我最喜欢的.实际上这是我取消资格的第一个,因为它是"共享"数据库.但经过各种可能性后,在我看来,这是唯一可行的.如果我想使用某种缓存,还有一些额外的复杂性,因为需要分布式缓存.

我真的会使用一些建议和意见如何处理架构,因为这非常棘手,很多事情都可能出错.

非常感谢,

卢卡斯

小智 5

我认为现在基于 Google Zanzibar 的方法最适合此目的。在将服务彼此联系得更紧密的同时,因为每个 ACL 相关请求都必须与 zanzibar 服务对话以评估权限,Google 关于 zanzibar 的论文很好地描述了他们如何解决延迟和最终一致性问题(或中的“新敌人”问题)。这个案例)。

这几乎是“共享数据库”方法,但具有特定于问题的数据库存储方式。

OSS 实现可以参见 SpiceDB(支持 CockroachDB 作为后端)或 Ory Kratos 等。


小智 3

我对您的授权要求没有完整、清晰的了解。我假设经过身份验证的用户和域对象/实体权限之间存在相关性。

需要考虑的一种选择是定义与域对象/实体权限相对应的用户属性,并实施基于属性的访问控制 (ABAC) 策略。

这些属性与用户身份绑定并存储在存储库中,并在执行身份验证时检索。