英文:
KeyCloak Group ID in Token missing
问题
我正在设置一个全新的KeyCloak实例,我正在尝试实现以下目标:
用户将被分配到以下位置:
- 组
- 这些组将获得客户特定的角色
例如,我有一个名为"Publishers"的角色,以及几个出版商的组:Publisher1、Publisher2等等。
因此,当用户登录时,我可以确定他是否是出版商,然后为他提供网站上的特定功能集。组将缩小他将接收的所有信息。
就像角色将为他提供对REST API的访问权限,而组将过滤他将收到的结果。
在SQL中:SELECT * FROM xyz where publisher_id = ?
在令牌中,我希望看到这些信息。当使用评估功能时,我目前收到以下信息:
{
"jti": "3e96fc9d-b1dc-428a-8f8e-0661f9cf265b",
"exp": 1578303161,
"nbf": 0,
"iat": 1578302861,
"iss": "https://prodo-sso-ti.ariva-services.de/auth/realms/PRODO",
"aud": "account",
"sub": "55bed571-dd3b-4282-8688-5da543517a49",
"typ": "Bearer",
"azp": "dashboard",
"auth_time": 0,
"session_state": "12ab2b8c-dc9a-42ca-b106-1a213dd38fc0",
"acr": "1",
"allowed-origins": [
"https://secretlink"
],
"realm_access": {
"roles": [
"offline_access",
"uma_authorization"
]
},
"resource_access": {
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
},
"dashboard": {
"roles": [
"Publisher"
]
}
},
"scope": "openid profile email",
"group_membership": [
"/Publisher1"
],
"email_verified": true,
"name": "My Name",
"preferred_username": "mb",
"locale": "de",
"given_name": "My",
"family_name": "Name",
"email": "my@name.de"
}
我启用了Group Membership Mapper以获取用户所在的组。问题是,我只获取到组的名称,而我需要一些更有用的信息,比如一个ID。因此,我尝试向组中添加一个名为"publisher_id"的属性,其数值为"1"。
如何才能在组成员信息或其他地方获取到这个"publisher_id"呢?或者也许我走错了路,有其他方法可以实现这个目标?
我感谢任何提示
英文:
I am currently setting up a fresh KeyCloak instance and I am trying to achieve the following:
Users will be placed in
- Groups
- These Groups will get client specific roles
For example I have the Role "Publishers" and several groups of publisher: Publisher1, Publisher2, ...
So, when a user logs in, I can determine whether he is a publisher or not and then give him access to a specific set of features on the website.
The groups shall then narrow down all infos he will receive.
Just like the role will give him access to a REST API and the group will filter the results he will receive.
In SQL: SELECT * FROM xyz where publisher_id = ?
In the token I want to see these infos. When using the evaluate feature I currently receive this:
{
"jti": "3e96fc9d-b1dc-428a-8f8e-0661f9cf265b",
"exp": 1578303161,
"nbf": 0,
"iat": 1578302861,
"iss": "https://prodo-sso-ti.ariva-services.de/auth/realms/PRODO",
"aud": "account",
"sub": "55bed571-dd3b-4282-8688-5da543517a49",
"typ": "Bearer",
"azp": "dashboard",
"auth_time": 0,
"session_state": "12ab2b8c-dc9a-42ca-b106-1a213dd38fc0",
"acr": "1",
"allowed-origins": [
"https://secretlink"
],
"realm_access": {
"roles": [
"offline_access",
"uma_authorization"
]
},
"resource_access": {
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
},
"dashboard": {
"roles": [
"Publisher"
]
}
},
"scope": "openid profile email",
"group_membership": [
"/Publisher1"
],
"email_verified": true,
"name": "My Name",
"preferred_username": "mb",
"locale": "de",
"given_name": "My",
"family_name": "Name",
"email": "my@name.de"
}
I activated the Group Membership Mapper to get the Groups the user is in.
The problem is, that I only get the name of the Group while I need something more useful, like an ID.
So I tried to add an attribute to group "publisher_id" with numeric value "1".
How is it possible to get also this publisher_id in the group membership infos or somewhere else.
Or maybe I am on a wrong way and this could be achieved somehow different?
I appreciate any hints
答案1
得分: 2
有一种简单的方法可以将群组 ID 添加到令牌中:
- 为您的客户端创建一个新的客户端范围:
客户端范围 - 创建 - 客户端范围模板(受众模板) - your_client_name
- 在您的新客户端范围中创建一个新的映射器:
客户端范围 - your_client_name - 映射器 - 创建
- 设置一些名称,映射器类型必须是脚本映射器,然后将以下代码粘贴到脚本部分:
/**
* 可用变量:
* user - 当前用户
* realm - 当前领域
* token - 当前令牌
* userSession - 当前用户会话
* keycloakSession - 当前用户会话
*/
// 在这里插入您的代码...
var groups = [];
for each (var group in user.getGroups()) groups.push(group.getId());
token.setOtherClaims("groups_ids",
Java.to(groups, "java.lang.String[]")
);
不要忘记设置添加到访问令牌。
您将在您的令牌中看到它:
groups_ids
英文:
There is an easy way to add Groups Id to token:
- Create a new Client Scope for your Client:
> Clients Scopes -> Create -> Client Scope Template(Audience template) -> your_client_name
- Create a new Mapper in your new Client Scope
> Clients Scopes -> your_client_name -> Mappers -> Create
- Set some name, Mapper Type must be Script Mapper
and then paste this code to Script section:
/**
* Available variables:
* user - the current user
* realm - the current realm
* token - the current token
* userSession - the current userSession
* keycloakSession - the current userSession
*/
//insert your code here...
var groups = [];
for each (var group in user.getGroups()) groups.push(group.getId());
token.setOtherClaims("groups_ids",
Java.to(groups, "java.lang.String[]")
);
Do not forget to set Add to access token.
You will see it in your token:
groups_ids
答案2
得分: 0
通过这个curl命令,您可以查找特定组可用的角色:
curl --location --request GET 'http://localhost:8080/auth/admin/realms/adanic/groups/35324d42-3299-4ed3-ad07-8c9ea8c02e9b/role-mappings/realm/available'
而通过这个curl命令,您可以获取具有特定角色的用户列表:
curl --location --request GET 'http://localhost:8080/auth/admin/realms/adanic/roles/adanic-admin/users?first=0&max=100' \
--header 'Content-Type: application/json' \
--data-raw '{
"roles": [
{
"id": "0830ff39-43ea-48bb-af8f-696bc420c1ce",
"name": "user",
"description": "${role_create-client}",
"composite": false,
"clientRole": true,
"containerId": "kilid"
}
]
}'
希望这对您有所帮助。
英文:
by this curl you can find out which roles are available for a special group:
curl --location --request GET 'http://localhost:8080/auth/admin/realms/adanic/groups/35324d42-3299-4ed3-ad07-8c9ea8c02e9b/role-mappings/realm/available'
and by this curl you can get list of users with special role:
curl --location --request GET 'http://localhost:8080/auth/admin/realms/adanic/roles/adanic-admin/users?first=0&max=100' \
--header 'Content-Type: application/json' \
--data-raw '{
"roles": [
{
"id": "0830ff39-43ea-48bb-af8f-696bc420c1ce",
"name": "user",
"description": "${role_create-client}",
"composite": false,
"clientRole": true,
"containerId": "kilid"
}
]
}'
i wish it could help
答案3
得分: 0
你的问题有点旧了,但我有一个类似的问题,甚至没有可能在组中存储属性(因为我使用了自定义的UserStoreProvider
)。
一个“简单”的解决方案可能是实现一个自定义的OIDCAccessTokenMapper
,并自己创建所需的令牌。基于AbstractOIDCProtocolMapper
实现一个不是很复杂的。
更多或更少,您只需要实现并部署一个JAR文件到您的Keycloak中,其中包含一个类(扩展抽象类),该类实现了以下方法:
@Override
protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession, KeycloakSession keycloakSession, ClientSessionContext clientSessionCtx)
然后,在SPI描述符文件org.keycloak.protocol.ProtocolMapper
中引用此类。
接下来,您需要在Keycloak客户端配置中激活“协议映射器”。
英文:
Your question is bit old now - but I have a comparable problem and even don´t have the possibility to store attributes in groups (since I´m using a custom UserStoreProvider
).
An "easy" solution solution would perhaps be to implement a custom OIDCAccessTokenMapper
and create your needed token on your own. It´s not very complicated to implment one based on AbstractOIDCProtocolMapper
.
More or less you just have to implement and deploy a jar to your keycloak with a single class (extending the abstract class), wich implements
@Override
protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession, KeycloakSession keycloakSession, ClientSessionContext clientSessionCtx)
and reference this class in a spi descriptor file org.keycloak.protocol.ProtocolMapper
You then have to activate the "protocol mapper" in your keycloak client configuration.
答案4
得分: 0
-
主要思想是扩展Keycloak
-
复制keycloak-extends-0.0.1.jar到keycloak-15.0.2\standalone\deployments
-
登录到Keycloak
-
选择领域
-
打开客户端范围页面
-
点击创建
-
创建新的OpenID客户端(或编辑现有的客户端)
-
打开创建的客户端
-
点击映射器选项卡
-
点击创建
-
选择映射器类型组ID
-
输入名称和令牌声明名称
-
点击保存
英文:
the main idea is to extend the keycloack
-
Copy keycloak-extends-0.0.1.jar to keycloak-15.0.2\standalone\deployments
-
Login to Keycloak
-
Select realm
-
Open client scopes page
-
Click create
-
Create new openid client (or edit existing one)
-
Open the created client
-
Click on mappers tab
-
Click on create
-
Select mapper type group id
-
Enter name and token claim name
-
Click save
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论