You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用keycloak-spring-boot-starter时如何通过Keycloak Java API获取用户组等数据

问题核心原因

Keycloak Spring Boot适配器仅负责完成JWT访问令牌的合法性校验,所有能从KeycloakPrincipal、KeycloakSecurityContext中读取到的用户数据,本质都是已经被编码在JWT令牌声明(Claims)中的内容。
Keycloak默认颁发的访问令牌仅包含用户ID、用户名、邮箱这类核心基础字段,用户所属分组、自定义档案字段、映射角色这类信息默认不会写入令牌声明,因此你仅能拿到用户ID,并非适配器功能缺失。

最优实现:通过Keycloak令牌映射注入用户数据

不需要额外调用Admin接口,仅需在Keycloak管理台配置规则,将需要的用户数据直接写入访问令牌,即可在现有代码中直接读取,这也是Keycloak官方推荐的常规用户数据获取方案,性能优于服务端远程调用:

  • 操作入口:Keycloak管理台 -> 对应test域 -> 客户端 -> 选中你当前使用的spring-boot-client客户端 -> 进入【Mappers】配置页
  • 针对需获取的信息创建对应映射器,确保所有映射器都勾选【Add to access token】开关:
    • 获取用户所属分组:创建类型为Group Membership的映射器,设置Token声明名称为groups,保存后所有颁发给该客户端的令牌都会携带用户全量分组路径信息
    • 获取自定义用户档案字段(如工号、手机号):创建类型为User Attribute的映射器,选中需要暴露的用户属性,设置对应声明名称即可
    • 获取域/客户端角色:分别创建类型为User Realm Role/User Client Role的映射器,勾选写入访问令牌
  • 配置完成后无需修改适配器逻辑,直接在现有接口中通过Token读取自定义声明即可,示例代码:
@GetMapping("/ping")
public ResponseEntity<Map<String, Object>> ping(KeycloakPrincipal<KeycloakSecurityContext> principal) {
    IDToken token = principal.getKeycloakSecurityContext().getToken();
    // 读取令牌中注入的分组数据
    List<String> userGroups = (List<String>) token.getOtherClaims().get("groups");
    // 读取令牌中注入的自定义用户属性
    String userPhone = (String) token.getOtherClaims().get("phoneNumber");
    return ResponseEntity.ok(Map.of(
        "userId", token.getSubject(),
        "groups", userGroups,
        "phone", userPhone
    ));
}
现有配置修正

你的YAML配置存在逻辑冲突与拼写错误,会影响部分功能的正常运行:

  • 配置中同时设置public-client: true、客户端secret、bearer-only: true,三者逻辑矛盾:public-client: true代表无密钥的公共客户端,与你配置的客户端secret不兼容,需将public-client改为false,匹配你服务作为纯资源服务器的定位。
  • 权限配置存在拼写错误:第二个安全约束下的角色配置写为ADMINN,与实际的ADMIN角色名不匹配,会导致该规则对应的接口权限拦截失效,需修正拼写。
Keycloak Java API/Admin REST的适用场景

Keycloak Spring Boot适配器本身不会内置Keycloak服务端的操作客户端,适配器的核心作用仅为令牌校验与权限拦截。如果你需要的不是可静态注入令牌的字段,而是需要动态执行用户数据查询、属性修改、分组分配这类操作,才需要引入官方的keycloak-admin-client依赖,直接以Java API方式调用Keycloak服务,不需要手动拼接REST请求:

  • 引入与当前Keycloak版本对齐的依赖(适配12.0.4版本):
<dependency>
    <groupId>org.keycloak</groupId>
    <artifactId>keycloak-admin-client</artifactId>
    <version>12.0.4</version>
</dependency>
  • 复用现有YAML中的连接配置初始化Keycloak客户端实例,无需重复配置参数:
@Bean
public Keycloak keycloakClient(KeycloakProperties keycloakProperties) {
    return KeycloakBuilder.builder()
            .serverUrl(keycloakProperties.getAuthServerUrl())
            .realm(keycloakProperties.getRealm())
            .clientId(keycloakProperties.getResource())
            .clientSecret(keycloakProperties.getCredentials().getSecret())
            .grantType(OAuth2Constants.CLIENT_CREDENTIALS)
            .build();
}
  • 直接通过实例调用对应方法即可完成用户数据查询,无需手动编写HTTP请求:
// 根据当前用户ID查询所属分组
UserResource currentUser = keycloakClient.realm("test").users().get(token.getSubject());
List<GroupRepresentation> userGroups = currentUser.groups();

这类远程调用仅适用于动态操作场景,获取常规用户档案数据无需使用该方式。


内容的提问来源于stack exchange,提问作者sushanthreddyu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.24 14:24:06