【问题标题】:Authorization mechanism in Keycloak looking in DB for roles/permissionsKeycloak 中的授权机制在数据库中查找角色/权限
【发布时间】:2021-01-02 23:25:29
【问题描述】:

我需要在 Keycloak 中实现授权机制,该机制根据角色查看我客户的数据库以获得用户的权限。

我无法在 Keycloak 的管理控制台中管理这些角色和权限,但我必须编写一些 SPI 来实现我的授权逻辑。类似于实现用户存储提供程序以在数据库中查找用户/密码验证。

但我找不到如何实现它。我认为,在身份验证过程中为用户获取有效令牌后,应用程序应发送该令牌以及执行操作所需的权限,以便 Keycloak(我自己的 SPI 实现)将验证令牌并搜索数据库以授予权限.

也许授权流程和我想的不一样(我之前写的)。

任何线索将不胜感激。

应用应该如何将token+权限发送给Keycloak?

如何实现响应此类请求并验证令牌的 SPI?

【问题讨论】:

  • 您使用什么数据库来存储用户和角色?你有办法将 jar 部署到 keycloak 服务器吗?
  • @AbrahamCiokler 这是一个 Oracle 数据库,是的,我已经为 Keycloak 部署了一个用户存储提供程序,因此我可以在我的问题中提到的同一个数据库中对用户进行身份验证。我认为必须有一些类似于 User Storage Provider 的机制来做基于 DB 查询的资源访问授权。

标签: java authorization keycloak


【解决方案1】:

回答您的第一个问题:Keycloak 将为您处理授权流程,您无需担心那部分。您需要做的就是通过实现UserStorageProvider 接口的方法来提供用户存储SPI。 密钥斗篷文档:https://www.keycloak.org/docs/latest/server_development/index.html#_user-storage-spi

要添加角色/权限,您需要实现UserModel 接口,该接口具有处理角色/权限的方法。密钥斗篷文档:https://www.keycloak.org/docs/latest/server_development/index.html#model-interfaces

要将这两者结合起来,您可以使用 UserStorageProvider 从 Oracle 数据库中获取用户记录并填写 UserModel 字段(电子邮件、姓名、角色等)。

Ex 伪代码:

注意:查看 keycloak 文档以获得更详细的演练:https://www.keycloak.org/docs/latest/server_development/index.html#simple-read-only-lookup-example

public class OracleDbUserStorageProvider implements UserStorageProvider, UserLookupProvider {

   private Map<String, UserModel> loadedUsers = new HashMap<>();

   private OracleDbRepository oracleDbRepository;

​   @Override
   ​public UserModel getUserByUsername(String username, RealmModel realm) {
       ​UserModel user = loadedUsers.get(username);
       ​if (user == null) {
           ​OracleUser oracleUser = oracleDbRepository.getUser(username);
           ​if (oracleUser != null) {
               ​user = convertToUserModel(oracleUser);
               ​loadedUsers.put(username, user);
           ​}
       ​}
       ​return user;
   ​}

   private UserModel convertToUserModel(OracleUser oracleUser) {
        // take oracleUser attributes and assign to a UserModel instance
        return userModel; // user model converted
   }

}

希望这可以帮助您朝着正确的方向前进。

【讨论】:

  • 我不明白这将如何工作。一旦 getUserByUsername(...) 返回的用户包含其角色/权限作为属性,Keycloak 就会返回一个不包含该信息的 JWT 令牌。如果用户(由令牌标识)具有权限,服务应该如何询问 Keycloak?
  • 你试过了吗?根据您的评论,我假设您已经尝试过这种方法并且它没有用。如果是这种情况,那么总是有这样的方法:不在 JWT 令牌中发送角色/权限,而是在用户登录时在您的应用程序中获取它们。我过去用 spring 做过这个。这样做的缺点是您需要为每个请求获取角色,但优点是令牌将包含更少的信息,这使其更安全且占用空间更小。像所有事情一样,这是一种权衡。您在应用程序中使用哪种技术堆栈?
  • 我在我的 UserModel (getRoleMappings().add(...)) 中添加了角色,它出现在令牌中。我想正确的方法是我的 Web 服务服务器在令牌中查找正确的角色,然后针对 Keycloak 验证令牌(它已签名、未过期等)。我试图验证 Keycloak 中的角色/权限,但我现在认为这个逻辑必须在我的服务器中实现。谢谢。
  • 没错。您的应用程序负责确保用户具有访问特定资源(如数据库记录或页面)的适当角色。 Keycloak 应该只关心用户登录、检索其角色和保持用户会话。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-10
  • 2020-12-07
  • 1970-01-01
  • 2019-05-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多