📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

适用版本: 7.x-8.x

1. 错误异常的基本描述 #

Failed to exchange code for Id Token using the Token Endpoint. 表示 Elasticsearch 在 OIDC 认证流程中,已成功获取授权码(Authorization Code),但在向 IdP(身份提供商)的 Token Endpoint 发起 HTTP 请求以交换 ID Token 时失败。

该异常通常发生在用户登录回调阶段,是 Elasticsearch 安全模块中 OpenIdConnectAuthenticator 抛出的一层包装异常,其根因(cause)才是真正需要关注的信息。

常见现象 #

  • 用户在浏览器中完成 IdP 登录授权后,被重定向回 Elasticsearch/Kibana 时看到登录失败页面。
  • Elasticsearch 日志中出现完整异常栈,根因可能是 ConnectExceptionSocketTimeoutExceptionSSLHandshakeException 等。
  • 如果是偶发网络抖动,表现为少量用户间歇性登录失败,且重试后可能成功。
  • 在极端情况下,所有用户均无法登录,这通常意味着 Token Endpoint 地址配置错误或 IdP 服务不可用。

典型报错与异常栈 #

实际日志中常见的异常链如下:

ElasticsearchSecurityException: Failed to exchange code for Id Token using the Token Endpoint.
Caused by: java.net.ConnectException: Connection refused
    at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
    at org.apache.http.nio.reactor.ssl.SSLIOSession.renegotiate(SSLIOSession.java:287)
    ...

或:

ElasticsearchSecurityException: Failed to exchange code for Id Token using the Token Endpoint.
Caused by: java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    ...

2. 为什么会发生这个错误 #

Elasticsearch 的 OIDC 认证流程分为两个阶段:先通过浏览器重定向获取授权码,再在后端用授权码调用 Token Endpoint 换取 ID Token。本异常恰好发生在第二阶段。

常见原因包括:

  • Token Endpoint 地址不可达op.token_endpoint 配置错误、DNS 解析失败、或目标服务未启动。
  • HTTPS 证书校验失败:IdP 使用自签名证书,而 Elasticsearch 未配置信任该证书,导致 SSL 握手失败。
  • 网络策略阻断:防火墙、安全组、代理或网关拦截了 Elasticsearch 节点到 IdP 的 outbound 请求。
  • IdP 响应超时:Token Endpoint 处理缓慢或负载过高,超过 Elasticsearch 的默认 HTTP 超时时间。
  • 请求被取消或连接被重置:中间代理(如 Nginx、Envoy)因配置不当主动断开连接。
  • 授权码已失效或重复使用:极少数情况下,授权码有效期极短,或存在并发回调导致 code 被重复使用。

3. 如何排查这个异常 #

排查时建议按以下顺序进行:

  1. 查看完整异常栈:先确认根因是连接失败、读取超时还是 SSL 异常,这决定了后续排查方向。
  2. 检查 op.token_endpoint 配置:在 elasticsearch.yml 中确认 OIDC 配置中的 op.token_endpoint 值是否正确,并与 IdP 的元数据文档(/.well-known/openid-configuration)核对。
  3. DNS 解析验证:在 Elasticsearch 节点上执行 nslookupdig 命令,确认 Token Endpoint 的域名能正确解析。
  4. 直接连通性测试:在 Elasticsearch 节点上使用 curl 手动访问 Token Endpoint,验证网络可达性和 TLS 握手是否正常。
  5. 对照 IdP 访问日志:确认请求是否真正到达 IdP,以及 IdP 侧是否返回了错误响应。
  6. 检查中间代理:如果请求经过企业代理或网关,检查是否被 WAF、限流规则或 Header 改写策略影响。

排查时需要注意的问题 #

  • 不要只看异常的表面信息,必须查看 Caused by 链中最底层的异常类型和消息。
  • 如果 Elasticsearch 节点配置了自定义 xpack.security.http.ssl 或 JVM 信任库,需确认 IdP 的 CA 证书已被正确导入。
  • 企业内网环境中,IdP 可能只允许通过代理访问,需确认 http.proxy 或 JVM 代理参数已正确设置。

4. 如何解决这个错误 #

常用修复思路 #

  • 修正 Token Endpoint 地址:确保 op.token_endpoint 与 IdP 实际提供的地址完全一致,注意是否遗漏 /token 路径或协议头。
  • 修复 TLS 信任问题:将 IdP 的 CA 证书导入 JVM 信任库,或在 elasticsearch.yml 中通过 xpack.security.authc.realms.oidc.<realm_name>.ssl.truststore 配置专用信任库。
  • 放通网络策略:在防火墙、安全组或网络策略中放通 Elasticsearch 节点到 IdP Token Endpoint 的访问权限(通常为 443 端口)。
  • 调整超时设置:如果 IdP 响应较慢,可通过调整 JVM 或 Apache HttpClient 的相关参数放宽超时限制(需参考具体版本文档)。
  • 检查代理配置:若请求需经过代理,在 elasticsearch.yml 中配置 http.proxy 相关参数,或在 JVM 启动参数中添加 -Dhttps.proxyHost=... -Dhttps.proxyPort=...

示例:使用 curl 验证 Token Endpoint 连通性 #

# 替换为实际的 Token Endpoint 地址
curl -v -X POST "https://idp.example.com/oauth2/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code&code=test_code&redirect_uri=https://es.example.com"

如果 curl 命令也失败,说明问题在网络层或 IdP 侧,而非 Elasticsearch 配置本身。

后续注意事项与推荐建议 #

  • 为 OIDC 认证配置健康检查或监控,在 IdP 不可达时快速感知。
  • 在变更 IdP 配置(如旋转证书、修改 Endpoint 地址)前,先在测试环境验证 Elasticsearch 侧连通性。
  • 对生产环境的 OIDC 配置变更采用灰度发布策略,避免所有用户同时无法登录。

借助 INFINI 产品提升排障效率 #

  • INFINI Console 适合查看集群健康度、节点日志和错误趋势,帮助快速判断认证失败是局部问题还是系统性问题。
  • INFINI Gateway 可部署在 Elasticsearch 前面做请求观测和流量治理,在 OIDC 认证异常时提供完整的请求链路可视性。

5. 小结 #

Failed to exchange code for Id Token using the Token Endpoint. 是一个典型的 OIDC 认证第二阶段异常,其根因多半位于网络连通性、TLS 配置或 IdP 可用性层面。排查时应从最底层的 Caused by 异常入手,结合 DNS 解析、直连测试、IdP 日志和网络策略逐一验证,而不是仅停留在 Elasticsearch 配置字段本身。

相关错误 #

附:日志上下文 #

public void failed(Exception ex) {
    tokensListener.onFailure(
        new ElasticsearchSecurityException("Failed to exchange code for Id Token using the Token Endpoint.", ex)
    );
}