【问题标题】:KeyCloak Group ID in Token missing令牌中的 KeyCloak 组 ID 丢失
【发布时间】:2020-01-06 09:39:20
【问题描述】:

我目前正在设置一个新的 KeyCloak 实例,并且我正在尝试实现以下目标: 用户将被放置在 - 团体 - 这些组将获得客户特定的角色

例如,我有“发布者”角色和几组发布者: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"
}

我激活了组成员映射器以获取用户所在的组。 问题是,当我需要一些更有用的东西(比如 ID)时,我只获得了 Group 的名称。 所以我尝试将属性添加到具有数值“1”的组“publisher_id”。

如何在组成员信息或其他地方也获得此 publisher_id。 或者也许我走错了路,这可能会以某种不同的方式实现?

感谢任何提示:)

【问题讨论】:

  • 你能解决这个问题吗?我正在尝试在令牌中获取组 ID

标签: keycloak


【解决方案1】:

有一种简单的方法可以将 Groups Id 添加到令牌:

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

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

  1. 在您的新 Client Scope 中创建一个新 Mapper

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

  1. 设置一些名称,Mapper Type必须是Script Mapper

然后将此代码粘贴到脚本部分:

/**
 * 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[]")
);

不要忘记设置添加到访问令牌

您将在您的令牌中看到它: groups_ids

【讨论】:

  • Script Mapper 是否仅在较新版本的 KeyCloak 中可用?我目前正在使用 9.0.3 并且在那里看不到 Script Mapper :(
  • 老实说,我没有使用以前的版本,所以我不知道 :) 尝试this 解决方案,希望对您有所帮助。
  • 但是当我阅读这篇文章时,我发现 Script Mapper 将从管理控制台中删除,因为这不安全。来自文档:管理员无法将脚本上传到服务器。此行为可防止在意外执行恶意脚本时对系统造成潜在损害。管理员应始终使用 JAR 文件将脚本直接部署到服务器,以防止在运行时运行脚本时受到攻击。
  • 任何想法如何在没有Script Mapper 的情况下做到这一点?
【解决方案2】:

通过这个 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"
       }
   ]
}'

希望能帮到你

【讨论】:

    【解决方案3】:

    您的问题现在有点老了 - 但我有一个类似的问题,甚至无法将属性存储在组中(因为我使用的是自定义 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 客户端配置中激活“协议映射器”。

    【讨论】:

      【解决方案4】:

      主要思想是扩展keycloack

      1. Download keycloak-extends-0.0.1.jar

      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. 点击保存

      【讨论】:

        猜你喜欢
        • 2020-11-23
        • 1970-01-01
        • 2019-08-10
        • 1970-01-01
        • 2021-10-08
        • 2018-09-07
        • 2020-05-01
        • 2018-03-11
        • 1970-01-01
        相关资源
        最近更新 更多