如何 read/import 从外部 IDP 到 Keycloak 的角色
How to read/import the roles from an external IDP into Keycloak
我有一个使用 Keycloak 11.0.2 保护的 spring 启动应用程序,我的 Keycloak 设置如下:
- 一个名为
Central
的领域,具有一个角色 CentralWebUser
和一个客户端 SpringWeb
。客户有
Access Type
: public
并且只启用了一个流,即 Standard Flow Enabled
Valid Redirect URIs
: http://localhost:8000/*
- 名为
SpringApp
的 2ª 领域,具有角色 WebUser
和客户端 spring_brokering
- 名为
springuser
且领域角色为 WebUser
的用户
- 客户端
spring_brokering
只有Standard Flow Enabled
设置为ON,Valid Redirect URIs
:http://localhost:8080/*,Access Type
:Confidential
第二个领域是第一个领域的IDP。因此,要登录用户,请转到 Central
登录页面并选择 IDP SpringAppIDP
。
IDP配置如下:
alias
: SpringAppIDP
,除了启用的选项 之外,其他所有内容都是 OFF
- 授权 URL、令牌 URL 等设置为
SpringApp
端点的 URL(e.g.,
Authorization URL
: http://127.0.0.1:8080/auth/realms/SpringApp/protocol/openid-connect/auth)
- 客户端 ID 和客户端密码分别是
spring_brokering
及其密码。
在 Spring 方面,我有以下属性值得一提:
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
及其密码。登录成功,但我得到一个 access denied,这意味着用户 springuser
没有角色 WebUser
。但是,该角色已分配给第二个领域内的该用户(即 SpringApp
)。
有趣的是,如果在第一个领域中我创建了一个身份提供者映射器 External Role to Role
(在 IDP SpringAppIDP
配置中)将 WebUser
的外部角色映射到 CentralWebUser
并将 spring 属性更改为 :
keycloak.security-constraints[0].authRoles[0]=CentralWebUser
keycloak.security-constraints[0].securityCollections[0].patterns[0]=/services/*
我可以登录,这意味着 Keycloak 知道用户具有 WebUser
角色,因此将该角色映射到 CentralWebUser
角色。
我想知道是否可以将角色从外部 IDP 显式导入到内部 IDP?或者,如果(以及如何)我可以代表用户请求一个令牌,该令牌将从该令牌中的 Central
和 SpringWeb
领域拥有该用户的角色,而无需显式创建角色每个用户角色的映射器。
I would like to know if it is possible to explicitly import the roles
from an external IDP into an internal one? Or if (and how) can I
request a token in behalf to the user that would have that users'
roles from both the Central and SpringWeb Realm in the that token,
without having to explicitly creating a Role Mapper for each user
role.
在没有为每个用户角色显式创建角色映射器的情况下,我找到的唯一解决方案是扩展 Keycloak 代码;这有明显的缺点。
回想起来,实际上 Keycloak 不提供开箱即用的自动从 外部导入所有角色的方法是有道理的 国内流离失所者。例如,如果我使用 Google 作为外部 IDP,为什么我的内部 IDP( 即 ,Keycloak)要关心 [=68= 使用的角色的确切名称]?!。最有可能的是,这些角色对内部 IDP 来说毫无意义,而当它们有意义时,它们可能有不同的名称。无论如何,对于那些例外情况,可以使用 Role Mapper 功能。
然而,为了使过程自动化一点,我创建了一个文件,将 internal IDP 的角色映射到 external IDP ,例如:
ROLE A | ROLE B
....
我还有一个 JSON 文件,其中包含角色映射器示例的 模板 ,其中包含一些标记,之后将被替换(例如, 字段 role
和 external.role
).
使用脚本,我读取具有角色之间映射的文件,并使用Keycloak Admin REST API创建角色、映射器等。
我用过的逻辑如下:
- 如果角色在external IDP中不存在我就跳过了,假设是错误的;
- 如果 internal IDP 中不存在该角色,我将其创建为领域角色;为此,我使用端点
POST /{realm}/roles
- 最后,我使用端点
POST /{realm}/identity-provider/instances/{alias}/mappers
和 JSON
模板角色映射器文件的内容(相应地替换了它的标签)创建了角色映射器。
不在 external IDP 中创建领域角色的理由是 external IDP 中的所有角色都应该已经加载无论如何已经来自 LDAP。对于 internal IDP,我确实创建了,因为对于映射 1 到 1,来自 LDAP 的角色(加载到 external IDP 中是可以预期的) 尚未在 internal IDP 上创建。
我有一个使用 Keycloak 11.0.2 保护的 spring 启动应用程序,我的 Keycloak 设置如下:
- 一个名为
Central
的领域,具有一个角色CentralWebUser
和一个客户端SpringWeb
。客户有Access Type
:public
并且只启用了一个流,即Standard Flow Enabled
Valid Redirect URIs
: http://localhost:8000/*
- 名为
SpringApp
的 2ª 领域,具有角色WebUser
和客户端spring_brokering
- 名为
springuser
且领域角色为WebUser
的用户
- 客户端
spring_brokering
只有Standard Flow Enabled
设置为ON,Valid Redirect URIs
:http://localhost:8080/*,Access Type
:Confidential
- 名为
第二个领域是第一个领域的IDP。因此,要登录用户,请转到 Central
登录页面并选择 IDP SpringAppIDP
。
IDP配置如下:
alias
:SpringAppIDP
,除了启用的选项 之外,其他所有内容都是 - 授权 URL、令牌 URL 等设置为
SpringApp
端点的 URL(e.g.,
Authorization URL
: http://127.0.0.1:8080/auth/realms/SpringApp/protocol/openid-connect/auth) - 客户端 ID 和客户端密码分别是
spring_brokering
及其密码。
OFF
在 Spring 方面,我有以下属性值得一提:
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
及其密码。登录成功,但我得到一个 access denied,这意味着用户 springuser
没有角色 WebUser
。但是,该角色已分配给第二个领域内的该用户(即 SpringApp
)。
有趣的是,如果在第一个领域中我创建了一个身份提供者映射器 External Role to Role
(在 IDP SpringAppIDP
配置中)将 WebUser
的外部角色映射到 CentralWebUser
并将 spring 属性更改为 :
keycloak.security-constraints[0].authRoles[0]=CentralWebUser
keycloak.security-constraints[0].securityCollections[0].patterns[0]=/services/*
我可以登录,这意味着 Keycloak 知道用户具有 WebUser
角色,因此将该角色映射到 CentralWebUser
角色。
我想知道是否可以将角色从外部 IDP 显式导入到内部 IDP?或者,如果(以及如何)我可以代表用户请求一个令牌,该令牌将从该令牌中的 Central
和 SpringWeb
领域拥有该用户的角色,而无需显式创建角色每个用户角色的映射器。
I would like to know if it is possible to explicitly import the roles from an external IDP into an internal one? Or if (and how) can I request a token in behalf to the user that would have that users' roles from both the Central and SpringWeb Realm in the that token, without having to explicitly creating a Role Mapper for each user role.
在没有为每个用户角色显式创建角色映射器的情况下,我找到的唯一解决方案是扩展 Keycloak 代码;这有明显的缺点。
回想起来,实际上 Keycloak 不提供开箱即用的自动从 外部导入所有角色的方法是有道理的 国内流离失所者。例如,如果我使用 Google 作为外部 IDP,为什么我的内部 IDP( 即 ,Keycloak)要关心 [=68= 使用的角色的确切名称]?!。最有可能的是,这些角色对内部 IDP 来说毫无意义,而当它们有意义时,它们可能有不同的名称。无论如何,对于那些例外情况,可以使用 Role Mapper 功能。
然而,为了使过程自动化一点,我创建了一个文件,将 internal IDP 的角色映射到 external IDP ,例如:
ROLE A | ROLE B
....
我还有一个 JSON 文件,其中包含角色映射器示例的 模板 ,其中包含一些标记,之后将被替换(例如, 字段 role
和 external.role
).
使用脚本,我读取具有角色之间映射的文件,并使用Keycloak Admin REST API创建角色、映射器等。
我用过的逻辑如下:
- 如果角色在external IDP中不存在我就跳过了,假设是错误的;
- 如果 internal IDP 中不存在该角色,我将其创建为领域角色;为此,我使用端点
POST /{realm}/roles
- 最后,我使用端点
POST /{realm}/identity-provider/instances/{alias}/mappers
和JSON
模板角色映射器文件的内容(相应地替换了它的标签)创建了角色映射器。
不在 external IDP 中创建领域角色的理由是 external IDP 中的所有角色都应该已经加载无论如何已经来自 LDAP。对于 internal IDP,我确实创建了,因为对于映射 1 到 1,来自 LDAP 的角色(加载到 external IDP 中是可以预期的) 尚未在 internal IDP 上创建。