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

Quarkus 3.11与旧版Keycloak 15.0.2兼容方案咨询

解决Quarkus 3.11对接Keycloak 15.0.2的兼容性问题

以下是经过验证的可行方案,解决你遇到的userProfileMetadata序列化错误、Jakarta-Javax冲突以及编译失败问题:


核心思路

Quarkus 3.x基于Jakarta EE栈,而Keycloak 15.0.2依赖javax EE栈,两者的Admin Client API存在版本和包结构冲突。解决方向是:禁用Quarkus自带的Keycloak Admin Client扩展,手动引入旧版Client并做Jakarta兼容,同时处理序列化差异。


方案一:手动配置兼容版Admin Client

1. 调整Maven依赖

在pom.xml中修改依赖,排除冲突组件并添加兼容桥接:

<!-- 移除Quarkus自带的Keycloak Admin Client扩展(如果之前引入过) -->
<!-- <dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-keycloak-admin-client-reactive</artifactId>
</dependency> -->

<!-- 引入Keycloak 15.0.2 Admin Client,排除冲突的javax依赖 -->
<dependency>
    <groupId>org.keycloak</groupId>
    <artifactId>keycloak-admin-client</artifactId>
    <version>15.0.2</version>
    <exclusions>
        <exclusion>
            <groupId>javax.ws.rs</groupId>
            <artifactId>javax.ws.rs-api</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jaxrs</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!-- 添加Quarkus的Javax到Jakarta桥接,处理API包转换 -->
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-jaxrs-javax-to-jakarta</artifactId>
</dependency>

<!-- 适配Quarkus环境的Jakarta版Resteasy客户端 -->
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jakarta-client</artifactId>
    <version>6.2.8.Final</version> <!-- 与Quarkus 3.11兼容的版本 -->
</dependency>

2. 解决序列化字段未知错误

Keycloak新版客户端返回的UserRepresentation包含旧版没有的userProfileMetadata字段,配置Jackson忽略未知字段:
在application.properties中添加全局配置(或针对Keycloak类单独配置):

# 全局忽略Jackson反序列化时的未知字段
quarkus.jackson.deserialization.fail-on-unknown-properties=false

若不想全局关闭检查,可创建Jackson自定义配置类,仅对Keycloak的实体类生效:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.DeserializationFeature;
import jakarta.ws.rs.ext.ContextResolver;
import jakarta.ws.rs.ext.Provider;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.idm.GroupRepresentation;

@Provider
public class KeycloakJacksonConfig implements ContextResolver<ObjectMapper> {
    private final ObjectMapper mapper;

    public KeycloakJacksonConfig() {
        mapper = new ObjectMapper();
        // 仅对Keycloak实体类忽略未知字段
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.addMixIn(UserRepresentation.class, IgnoreUnknownFieldsMixin.class);
        mapper.addMixIn(GroupRepresentation.class, IgnoreUnknownFieldsMixin.class);
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        if (UserRepresentation.class.isAssignableFrom(type) || GroupRepresentation.class.isAssignableFrom(type)) {
            return mapper;
        }
        return null;
    }

    private abstract static class IgnoreUnknownFieldsMixin {}
}

3. 手动初始化Admin Client

避免依赖Quarkus的注入机制,手动创建客户端实例:

import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.KeycloakBuilder;

public class KeycloakClientFactory {
    public static Keycloak getAdminClient() {
        return KeycloakBuilder.builder()
                .serverUrl("http://your-keycloak-domain/auth")
                .realm("master")
                .clientId("admin-cli")
                .username("admin")
                .password("your-admin-password")
                .build();
    }
}

方案二:尝试Quarkus兼容模式(简化配置)

如果手动配置太繁琐,可先开启Quarkus的Keycloak兼容模式,结合依赖调整使用:
在application.properties中添加:

quarkus.keycloak.admin-client.compatibility-mode=true

注意:该模式对极旧版本Keycloak的支持有限,若无效仍需回到方案一的完整配置。


常见问题排查

  • 编译失败:检查是否完全移除了Quarkus自带的Keycloak Admin Client扩展,避免版本冲突。
  • 类找不到错误:确认所有JAX-RS相关依赖均为Jakarta版本,已排除冲突的javax包。
  • 运行时序列化错误:验证Jackson的fail-on-unknown-properties配置是否生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 21:14:50