Scala调用Keycloak获取用户列表报HTTP 404、连接拒绝错误排查
Keycloak获取用户列表报错问题定位
两类报错的直接原因
- 连接拒绝错误:属于正常网络层报错,说明你配置的
127.0.0.1:8080地址无服务监听,Keycloak未启动时必然触发,不属于代码逻辑问题。 - 启动Keycloak后报404 Not Found:属于请求路径错误,Keycloak服务端无法匹配到你请求的API地址,由代码配置错误导致。
代码中存在的具体问题
业务实现代码(NewUserService.scala)问题
- 硬编码realm名称覆盖配置
你已经从配置文件中读取了realm参数,但实际调用时写死了realm值:
// 错误写法:硬编码knoldus,未使用配置中读取的realm变量 val usersList = Future(Try(keycloakBuild.realm("knoldus").users().list()))
如果你的Keycloak服务中不存在名为knoldus的realm,请求会直接返回404。
2. serverUrl配置与Keycloak版本不匹配
不同版本Keycloak的默认API上下文路径不同,配置错误会直接导致404:
- Keycloak 17以下(WildFly发行版):默认上下文路径为
/auth,realmServerURL需要配置为http://127.0.0.1:8080/auth - Keycloak 17及以上(Quarkus发行版):默认上下文路径为根路径
/,realmServerURL配置为http://127.0.0.1:8080即可;如果手动修改了http-relative-path配置,需要对应调整路径。
- 客户端资源泄漏风险
每次调用getAllUsers方法都会新建一个Resteasy连接池客户端,没有配套的资源回收逻辑,服务长时间运行会出现连接泄漏,建议将Keycloak客户端实例初始化为单例复用,不要每次请求都新建。
单元测试代码完全失效
你写的Mock逻辑完全没有注入到业务代码中,跑测试时业务代码会真实调用KeycloakBuilder.builder()连接127.0.0.1:8080的真实服务,根本不会用到你Mock的对象,这也是测试时出现真实网络报错、404的核心原因:
- 你Mock的
KeycloakBuilder、ResteasyClientBuilder都是测试类里的局部变量,业务代码中是直接调用静态方法KeycloakBuilder.builder()、手动new了新的ResteasyClientBuilder实例,和你Mock的对象没有任何关联,Mock规则完全不生效。 - Mock返回值写法错误:
List(any[UserRepresentation]).asJava中的any[UserRepresentation]是参数匹配器,不能作为真实返回值,需要构造真实的UserRepresentation测试对象列表返回。
修复方案
- 核对本地部署的Keycloak版本,修正配置文件中
realmServerURL的值,确保和Keycloak的上下文路径一致。 - 将硬编码的realm值替换为配置中读取的
realm变量,同时确认Keycloak中已创建对应名称的realm,且使用的管理员账号拥有该realm下的用户查询权限。 - 重构单元测试:要么将Keycloak客户端初始化逻辑抽成可注入的依赖,通过参数传入
NewUserService,方便测试时注入Mock对象;要么使用PowerMock等工具MockKeycloakBuilder的静态方法,避免测试时发起真实网络请求。 - 修正测试中的Mock返回值,构造真实的测试用户数据返回,不要使用参数匹配器作为返回结果。
内容的提问来源于stack exchange,提问作者Aman Verma
相关产品推荐
相关产品推荐

