【问题标题】:Managing user permissions in keycloak and spring rest api在 keycloak 和 spring rest api 中管理用户权限
【发布时间】:2018-11-13 06:56:34
【问题描述】:

TL;DR

  • 目的:管理api权限:
    • OIDC 授权直接授权流程
    • 用户联合和身份验证源:LDAP
    • 权限存储:旧数据库
    • 客户端管理和身份验证:Keycloak
  • 问题:在 Keycloak 和 rest api 上管理用户权限的最佳做法是什么?

上下文

我们正在实现一个带有 spring 的 rest API,供移动应用程序和 SPA 使用。我们的用户帐户、权限、规则……以及所有数据都存储在一个自定义数据库中,供不同的单体应用程序使用。为了保护我们的 API,我们决定使用 Keycloak。

keycloak 服务器配置了用于用户联合的现有 LDAP 和用于移动客户端应用程序的“Direct grand flow”。对于第一个用例(身份验证),一切正常。

现在我们必须按如下方式管理用户权限:

  • 客户端应用程序应该知道用户显示/隐藏功能的权限

  • api 应该能够验证用户使用不同端点的权限

  • 用户权限是基于数据库中的一些规则,经常变化

据我了解,keycloak 可以使用硬编码或基于用户的策略来处理授权和细粒度权限,但不能以原生方式插入不同的授权源。因此,我想到了使用 Keycloak SPI 构建自定义角色映射器,从我将开发的自定义 api 中检索用户权限,然后将它们映射到访问令牌。

因此,我的访问令牌应如下所示:

"resource_access": {
    “My-client”: {
      “permissions”: [
        “Show-products”,
        “Buy-something”,
        “Display-prices”
      ]
    }
  },
  "username": “myUser”

然后移动应用程序应该能够根据令牌知道用户权限,并且我的无状态服务器端(API)应该能够在每次调用时访问用户权限以使用 spring 注释检查它们:

@PreAuthorize("hasRole('Show-products')")

问题

在第一次尝试后,我的解决方案似乎运行良好,但我仍然对这个选择存在一些安全问题,因为它不符合 keycloak 标准,并且在 keycloak 映射器中包含对不同后端的休息调用。

所以我想知道:

  • 将用户权限放在访问令牌声明上是否安全?
  • 如何保护对外部系统的 keycloak 访问(休息调用)以 检索权限?
  • 我是否应该依靠令牌声明来验证每个用户的权限? 在我的资源服务器中请求?
  • 是否有任何其他干净的解决方案/最佳实践来处理用户 在 keycloak 中来自外部源的权限?

免费信息

我正在使用:

  • Springboot 1.5.13.RELEASE
  • Keycloak-adapter-bom 3.4.3.Final
  • 独立 keycloak 服务器 3.4.3.Final

【问题讨论】:

  • 嗨@wadi3,你实现了吗?

标签: spring rest spring-security keycloak openid-connect


【解决方案1】:

关于您的问题:

- 将用户权限放在访问令牌声明上是否安全?

是的,功能可以(并且应该)在访问令牌上,并且您可以在业务层中做出一些决定(基于角色/访问声明)。但是请记住,令牌仅是 base 64 编码,并且可以被其他人复制并查看,因此它不应该包含秘密或特别机密的信息,通常你会在那里放置足够的关于用户的信息,以及它的一些当前权限/功能/声明。

如何保护 keycloak 访问外部系统(休息调用)以检索权限?

这取决于它是否需要从您的网络外部访问。如果没有,您可以让它不受保护(并且从外部不可用/或仅可用于某些特定 IP)。如果它可以从外部获得/或者您想用 keycloack 保护它,您可以拥有“机密”或“仅限承载”类型的客户端。我建议您研究 CORS 和令牌共享,这样您就可以将您已经创建的“访问令牌”用于其他端点,而无需再次进行身份验证。

我应该依靠令牌声明来验证资源服务器中每个请求的用户权限吗?

不完全确定您的意思。在 keycloak 中,资源服务器没有像典型的 oAuth2 舞蹈那样进行额外的资源授权(除非您的策略执行器被激活,但我相信您没有采用这种方法,而是使用映射器 SPI @auth 服务器来获得正确的角色?)

在 oAuth2 中,“资源服务器”有 2 个职责:1-提供资源和 2-执行额外的授权步骤。在 keycloak 世界中,这两个步骤由不同的参与者完成。第 1 步由您的应用程序完成,第 2 步仅在 keycloak 也激活策略执行时完成(这意味着 Keycloak 是身份验证服务器,从 oAuth2 角度来看也是“资源服务器”的一部分)

现在回到您的问题,如果资源服务器只是指您的应用程序提供内容,那么是的,您可以在那里使用声明,请记住声明(以及整个访问令牌)是由生成并数字签名的身份验证服务器,因此您可以在您的应用中毫无问题地使用这些声明(否则也不知道该怎么做)。

是否有任何其他干净的解决方案/最佳实践可以在 keycloak 中处理来自外部源的用户权限?

很难说,你可能已经注意到了;针对您的特定用例的网络文档非常有限;所以那里没有很多最佳实践的工作,你唯一真正的选择是使用带有自定义策略 SPI 的策略,这会带来其他挑战。我会说你的解决方案很好。

最好的问候。

【讨论】:

  • 您能否准确说明功能、声明和权限之间的区别? AFAIK 权限在 Keycloak 中非常具体,它们似乎需要authorization request。但是,我不确定应该在哪里设置能力(全局范围?)和权限之间的限制,因此我想澄清这一点。
猜你喜欢
  • 2015-06-24
  • 2023-01-09
  • 2021-07-20
  • 1970-01-01
  • 2022-07-11
  • 2019-06-27
  • 1970-01-01
  • 2012-12-24
  • 2014-04-12
相关资源
最近更新 更多