如何将角色从外部IDP读取/导入到Keycloak中

问题描述

我有一个受Keycloak 11.0.2保护的spring boot应用程序,我的Keycloak设置如下:

  • 名为Central的领域,角色为CentralWebUser,客户为SpringWeb。客户有
    • Access Typepublic且仅启用一个流,即Standard Flow Enabled
    • Valid Redirect URIs:http:// localhost:8000 / *
  • 名为SpringApp且角色为WebUser和客户端spring_brokering的2ª领域
    • 一个名为springuser用户,其角色为WebUser
    • 客户端spring_brokering仅将Standard Flow Enabled设置为ON,Valid Redirect URIs:http:// localhost:8080 / *和Access TypeConfidential

第二个领域是第一个领域的IDP。因此,要登录用户将转到Central登录页面并选择IDP SpringAppIDP

IDP配置如下:

在春季,我有以下值得一提的属性

server.port                         = 8000
keycloak.realm                      = Central
keycloak.auth-server-url            = http://localhost:8080/auth
keycloak.ssl-required               = external
keycloak.resource                   = SpringWeb
keycloak.public-client=true

keycloak.security-constraints[0].authRoles[0]=WebUser
keycloak.security-constraints[0].securityCollections[0].patterns[0]=/services/*

当我访问http://127.0.0.1:8080/services时,我被重定向到Keycloak Central领域登录页面,然后单击SpringAppIDP并输入用户名springuser及其密码。登录成功,但是我得到拒绝访问,这意味着用户springuser没有角色WebUser。但是,该角色是在第二个领域( SpringApp)内分配给该用户的。

有趣的是,如果我在第一个领域中创建一个身份提供者Mapper External Role to Role(在IDP SpringAppIDP配置中),将WebUser的外部角色映射到CentralWebUser并将弹簧属性更改为:

keycloak.security-constraints[0].authRoles[0]=CentralWebUser
keycloak.security-constraints[0].securityCollections[0].patterns[0]=/services/*

我能够登录,这意味着Keycloak知道用户具有WebUser角色,因此将该角色映射到CentralWebUser角色。

我想知道是否可以将角色从外部IDP显式导入到内部IDP中吗?或者,是否可以(以及如何)代表用户向令牌中的CentralSpringWeb领域中拥有该用户角色的用户请求令牌,而不必显式创建角色每个用户角色的映射器。

解决方法

我想知道是否可以显式导入角色 从外部 IDP 变成内部 IDP?或者如果(以及如何)我可以 代表将拥有该用户的用户请求令牌 该令牌中来自 Central 和 SpringWeb Realm 的角色, 无需为每个用户显式创建角色映射器 角色。

没有为每个用户角色明确创建角色映射器,我发现的唯一解决方案是扩展 Keycloak 代码;这有明显的缺点。

回想起来,实际上是有道理的,Keycloak 没有提供一种从外部 IDP 自动导入所有角色的开箱即用方式。例如,如果我使用 Google 作为外部 IDP,为什么我的内部 IDP(i.e.,Keycloak)应该关心 Google 使用的角色的确切名称?!。最有可能的是,这些角色对于内部 IDP 来说毫无意义,当它们有意义时,它们可能有不同的名称。无论如何,对于这些例外情况,您可以使用角色映射器功能。

尽管如此,为了使过程自动化,我创建了一个文件,将内部 IDP的角色映射到外部 IDP,例如:

ROLE A | ROLE B
....

我还有一个带有角色映射器示例的 模板 的 JSON 文件,其中包含一些稍后要替换的标签( 字段 role 和 { {1}})。

通过脚本,我读取具有角色之间映射关系的文件,并使用 Keycloak Admin REST API 创建角色、映射器等。

我使用的逻辑如下:

  • 如果该角色在外部 IDP 中不存在,我只是跳过并假设这是一个错误;
  • 如果内部 IDP 中不存在该角色,我会将其创建为 Realm 角色;为此,我使用端点 external.role
  • 最后,我使用端点 POST /{realm}/rolesPOST /{realm}/identity-provider/instances/{alias}/mappers 模板角色映射器文件的内容(相应地替换了其标签)创建了角色映射器。

不在 external IDP 中创建 Realm 角色的理由是 external IDP 中的所有角色应该已经从 LDAP 加载。对于内部 IDP,我确实创建了,因为可以预期,对于映射 1 到 1,来自 LDAP(加载到 外部 IDP)的角色尚未在其上创建内部 IDP。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...