Keycloak如何获取自定义属性到KeycloakPrincipal中?

53

通过身份验证,我可以在我的REST服务中获得主要信息

KeycloakPrincipal kcPrincipal = (KeycloakPrincipal) servletRequest.getUserPrincipal();

声明。

Keycloak主体不包含我需要的有关经过身份验证的用户的所有信息。 是否可以自定义我的自己的主体类型? 在keycloak-server-end上,我已经开发了一个用户联合提供程序。我看到UserModel可以向我的用户添加一组自定义属性。

是否可以在该代码中插入我的自定义主体?

是否可以从keycloak主体检索这些属性?

方法是什么?


https://dev59.com/PYjca4cB1Zd3GeqP0K_O - Vítor
3个回答

93

要添加自定义属性,您需要执行三个步骤:

  1. 在管理控制台中添加属性
  2. 添加声明映射
  3. 访问声明

第一个步骤可以在这里找到详细说明:https://www.keycloak.org/docs/latest/server_admin/index.html#user-attributes

添加声明映射:

  1. 打开您领域的管理控制台。
  2. 转到“客户端”并打开您的客户端
  3. 仅适用于“设置”> 访问类型机密或公共(非仅限承载人)
  4. 转到映射器
  5. 创建从您的属性到json的映射
  6. 勾选“添加到ID令牌”

访问声明:

final Principal userPrincipal = httpRequest.getUserPrincipal();

if (userPrincipal instanceof KeycloakPrincipal) {

    KeycloakPrincipal<KeycloakSecurityContext> kp = (KeycloakPrincipal<KeycloakSecurityContext>) userPrincipal;
    IDToken token = kp.getKeycloakSecurityContext().getIdToken();

    Map<String, Object> otherClaims = token.getOtherClaims();

    if (otherClaims.containsKey("YOUR_CLAIM_KEY")) {
        yourClaim = String.valueOf(otherClaims.get("YOUR_CLAIM_KEY"));
    }
} else {
    throw new RuntimeException(...);
}

我在使用自定义主题时,为一个自定义属性添加了这个东西。


我能够检索电子邮件ID、名字和姓氏,但无法检索自定义属性移动电话。我得到了大小为0的OtherClaims。 - Surya Movva
我的代码如下: KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) request. getUserPrincipal(); KeycloakPrincipal principal = (KeycloakPrincipal) token.getPrincipal(); IDToken idToken = principal.getKeycloakSecurityContext().getIdToken(); System.err.println("size "+otherClaims.size()+idToken.getEmail()+idToken.getFamilyName()); - Surya Movva
@SuryaMovva,您是否已在使用的客户端下的Keycloak管理控制台中添加了映射? - Turbut Alin
@TurbutAlin 你好。我有同样的问题。我无法看到添加到用户的新属性。我已经在我的客户端(Spring Boot应用程序)下添加了映射,但仍然没有收到新属性。你能帮忙吗?谢谢。 - troger19
链接已过期,正确的链接是https://www.keycloak.org/docs/latest/server_admin/index.html#user-attributes。 - lkamal
我的idToken始终为空。我确实获得了访问令牌。但是我不知道哪里出了问题。有什么建议吗? - denov

72
  • 选择用户 > 查找 > 点击ID > 到属性选项卡 > 添加属性 > 例如:电话 > 保存 enter image description here

  • 选择客户端 > 点击客户端ID > 到映射器选项卡 > 创建映射器

    enter image description here

    enter image description here

    enter image description here

  • 获取自定义属性

    enter image description here

    enter image description here

更新

  • 在群组级别上添加 '电话' 属性,将用户分配到该群组中,即可通过群组级别获得所有用户的 '电话' 属性

  • 返回映射器并使用 '聚合属性值 = true' 和 '多值 = true' 更新 '电话' ,您将获得包含来自群组和用户级别的两个属性的 '电话' 列表。如果保持 '聚合属性值 = false' 或 '多值 = false' ,则只会获得一个值,其中用户的 '电话' 属性将覆盖群组中的 '电话' 属性(这是有意义的)


8
感谢@Neeraj,我正在做你刚才发布的相同事情。我这边的问题是缓存。在添加映射或用户属性后,我需要在Keycloak管理控制台中清除领域缓存。之后,我就能够在otherClaims中看到这些属性了。希望这对大家有所帮助。 - troger19
1
@troger19,感谢您的评论,因为我没有想到那个问题,所以我花了数小时的时间。 - Neikius
2
谢谢您提供的解决方案。有没有办法将自定义属性应用于所有用户?我特别需要为通过我的LDAP提供程序导入的所有用户执行此操作。 - user1026498
感谢您的解决方案!它实现了我们想要的功能!我已经更新了您的答案,加入了组属性选项。 - Dmitri Algazin
我是KeyCloak的新手,正在使用最新版本6.0.1。你的回答真是太及时了——清晰、简洁、正确!谢谢。赞一个!! - sunitkatkar
@Neeraj 对于移动应用程序,当我通过RESTAPI (/ openid-connect / token)登录时,我想保留device_id、device_model、纬度和经度。 Keycloak支持吗? - Panup Pong

8

对于Keycloak版本> 18,映射器的配置已经移动到UI中:

Clients > Your selected client下的Client Scopes选项卡中,必须选择account-dedicated:

enter image description here

在那里可以添加自定义映射器:

enter image description here


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