令牌中缺少 KeyCloak 组 ID

3
我正在设置新的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。 因此,我尝试在群组中添加属性"publisher_id",其数值为"1"。

如何才能在群组成员信息或其他地方获取这个publisher_id呢? 或者也许我走错了路,可以以其他方式实现这个目标吗?

我很感激任何提示 :)


你能解决这个问题吗?我正在尝试获取令牌中的组ID。 - Stealth Rabbi
4个回答

2

添加组Id到令牌的简单方法如下:

  1. 为您的客户端创建一个新的客户端范围(Client Scope)

客户端范围(Client Scopes) -> 创建(Create) -> 客户端范围模板(Audience template) -> your_client_name(您的客户端名称)

  1. 在您的新的客户端范围(Client Scope)中创建一个新的映射器(Mapper)

客户端范围(Client Scopes) -> your_client_name(您的客户端名称) -> 映射器(Mappers) -> 创建(Create)

  1. 设置一些名称,映射器类型(Mapper Type)必须是脚本映射器(Script Mapper)

然后将以下代码粘贴到“脚本(Script)”部分:

/**
 * 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


脚本映射器只在较新版本的KeyCloak中可用吗?我目前使用的是9.0.3版本,但没有看到脚本映射器 :( - Barzille
老实说,我没有使用过以前的版本,所以我不知道 :) 尝试使用这个解决方案,希望能对你有所帮助。 - Влад Владович
但是当我阅读这篇文章时,我发现脚本映射器将从管理控制台中删除,因为它不安全。根据文档: 管理员无法将脚本上传到服务器。此行为可以防止恶意脚本在意外执行时对系统造成潜在的危害。管理员应始终使用JAR文件直接部署脚本到服务器,以防止在运行时执行脚本时遭受攻击。 - Влад Владович
有没有任何想法可以在没有“脚本映射器”的情况下完成它? - LeptonByte

0

主要思路是扩展Keycloak

  1. 下载keycloak-extends-0.0.1.jar

  2. 将keycloak-extends-0.0.1.jar复制到keycloak-15.0.2\standalone\deployments目录下


  • 登录 Keycloak
  • 选择领域
  • 打开客户端作用域页面
  • 点击创建
  • 创建新的 OpenID 客户端(或编辑现有客户端)
  • 打开已创建的客户端
  • 点击映射器选项卡
  • 点击创建
  • 选择映射器类型组 ID
  • 输入名称和令牌声明名称
  • 点击保存

enter image description here


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客户端配置中激活“协议映射器”。


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"
       }
   ]
}'

希望它能帮到你


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接