KeyCloak令牌中缺少群组ID。

huangapple go评论88阅读模式
英文:

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"呢?或者也许我走错了路,有其他方法可以实现这个目标?

我感谢任何提示 KeyCloak令牌中缺少群组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 KeyCloak令牌中缺少群组ID。

答案1

得分: 2

有一种简单的方法可以将群组 ID 添加到令牌中:

  1. 为您的客户端创建一个新的客户端范围

客户端范围 - 创建 - 客户端范围模板(受众模板) - your_client_name

  1. 在您的新客户端范围中创建一个新的映射器

客户端范围 - your_client_name - 映射器 - 创建

  1. 设置一些名称,映射器类型必须是脚本映射器,然后将以下代码粘贴到脚本部分:
/**
 * 可用变量:
 * 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:

  1. Create a new Client Scope for your Client:

> Clients Scopes -> Create -> Client Scope Template(Audience template) -> your_client_name

  1. Create a new Mapper in your new Client Scope

> Clients Scopes -> your_client_name -> Mappers -> Create

  1. 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

  1. 主要思想是扩展Keycloak

  2. 复制keycloak-extends-0.0.1.jar到keycloak-15.0.2\standalone\deployments


  1. 登录到Keycloak

  2. 选择领域

  3. 打开客户端范围页面

  4. 点击创建

  5. 创建新的OpenID客户端(或编辑现有的客户端)

  6. 打开创建的客户端

  7. 点击映射器选项卡

  8. 点击创建

  9. 选择映射器类型组ID

  10. 输入名称和令牌声明名称

  11. 点击保存

英文:

the main idea is to extend the keycloack

  1. Download keycloak-extends-0.0.1.jar

  2. Copy keycloak-extends-0.0.1.jar to keycloak-15.0.2\standalone\deployments


  1. Login to Keycloak

  2. Select realm

  3. Open client scopes page

  4. Click create

  5. Create new openid client (or edit existing one)

  6. Open the created client

  7. Click on mappers tab

  8. Click on create

  9. Select mapper type group id

  10. Enter name and token claim name

  11. Click save

KeyCloak令牌中缺少群组ID。

huangapple
  • 本文由 发表于 2020年1月6日 17:39:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/59609731.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定