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

适用版本: 7.x-8.9

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

Failed to get claims from the Userinfo Endpoint. 表示 Elasticsearch 的 OIDC(OpenID Connect)Realm 已经开始向身份提供方(Identity Provider,IdP)的 UserInfo Endpoint 取回用户 claims,但 HTTP 请求最终以失败回调结束。从源码看,这个异常出现在异步 HTTP 回调的 failed(Exception ex) 分支,因此它强调的是"请求执行失败",而不是"响应已返回但内容不合法"。

常见现象 #

  • Kibana 或其他依赖 OIDC 的应用在用户登录流程中,跳转回 Elasticsearch 后登录失败。
  • Elasticsearch 安全日志中出现 ElasticsearchSecurityException,并带有底层网络或 TLS 异常信息。
  • 同一个 Realm 的 token 交换可能成功(能拿到 access_token),但在补充 claims 阶段失败,导致用户无法完成认证。
  • 用户反复重定向到身份提供方登录页面,但每次返回后都报错,形成登录死循环。
  • 在 Elasticsearch 日志中可以看到 failed to get claims from the userinfo endpoint 关键字,伴随底层异常如 ConnectExceptionSocketTimeoutExceptionSSLHandshakeException

典型报错与异常栈 #

常见日志形态通常类似下面这样:

ElasticsearchSecurityException: Failed to get claims from the Userinfo Endpoint.
Caused by: java.net.ConnectException: Connection refused
	at org.elasticsearch.xpack.security.authc.oidc.OpenIdConnectRealm...

或者 TLS 相关错误:

ElasticsearchSecurityException: Failed to get claims from the Userinfo Endpoint.
Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed
	at sun.security.ssl.Alert.createSSLException(Alert.java:...)

或者超时错误:

ElasticsearchSecurityException: Failed to get claims from the Userinfo Endpoint.
Caused by: java.net.SocketTimeoutException: Read timed out
	at java.net.SocketInputStream.socketRead0(Native Method)

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

Failed to get claims from the Userinfo Endpoint. 的根因是"Elasticsearch 向 OIDC 身份提供方的 UserInfo Endpoint 发起的 HTTP 请求失败"。OIDC 认证流程中,Elasticsearch 在收到授权码(authorization code)并交换到 access_token 后,会调用 UserInfo Endpoint 获取用户详细信息(claims),如果这个请求失败,整个认证流程就会中断。

常见原因通常包括:

  • UserInfo Endpoint 地址不可达op.userinfo_endpoint 配置错误、DNS 解析失败、服务地址变更或网络被防火墙/安全组拦截。
  • TLS 握手失败:身份提供方的证书不受信任(CA 未导入)、证书过期、主机名校验失败(hostname verification)或 TLS 版本不兼容。
  • 身份提供方临时不可用:IdP 服务宕机、重启或负载过高,导致请求无法得到正常响应。
  • 请求超时或连接池异常oidc realm 的 http.connect_timeouthttp.socket_timeout 设置过小,或者连接池耗尽。
  • 认证信息问题:access_token 无效、过期或 scope 不足,导致 IdP 拒绝 UserInfo 请求(虽然这通常返回 HTTP 错误码,但在某些客户端配置下也可能触发异常)。
  • 代理配置错误:如果 Elasticsearch 需要通过代理访问外部 IdP,代理配置错误或代理服务不可用。
  • 节点退出或重启:在请求过程中 Elasticsearch 节点正在关闭,导致异步回调被取消或失败。

3. 如何排查和解决这个异常和解决这个异常 #

建议按"先查底层异常、再核配置、后测连通性"的顺序处理:

  1. 获取完整异常信息:从 Elasticsearch 安全日志中找到这个异常对应的底层 caused by,确定是网络问题、TLS 问题还是超时问题。

    # 查看 Elasticsearch 安全日志
    grep -r "Failed to get claims from the Userinfo Endpoint" /var/log/elasticsearch/
    grep -r "ElasticsearchSecurityException" /var/log/elasticsearch/ | tail -50
    
  2. 核对 OIDC Realm 配置:检查 elasticsearch.yml 中 OIDC Realm 的相关配置。

    # 查看 OIDC Realm 配置
    curl -X GET "localhost:9200/_cluster/settings?include_defaults=true&filter_path=*.xpack.security.authc.realms.oidc.*" -u elastic:password
    

    重点检查以下配置:

    • xpack.security.authc.realms.oidc.<realm_name>.op.userinfo_endpoint
    • xpack.security.authc.realms.oidc.<realm_name>.op.issuer
    • xpack.security.authc.realms.oidc.<realm_name>.ssl.*(TLS 相关配置)
    • xpack.security.authc.realms.oidc.<realm_name>.http.*(超时相关配置)
  3. 测试到身份提供方的连通性:从 Elasticsearch 节点直接测试到 IdP 的连通性和证书链。

    # 测试 HTTP/HTTPS 连通性
    curl -v https://your-idp-domain.com/oauth2/userInfo
       
    # 检查 TLS 证书
    openssl s_client -connect your-idp-domain.com:443 -showcerts
       
    # 检查 DNS 解析
    nslookup your-idp-domain.com
    
  4. 检查 TLS 信任配置:如果底层异常是 SSL 相关,需要确认 Elasticsearch 的 truststore 中包含 IdP 的 CA 证书。

    # 查看 Elasticsearch 使用的 truststore
    keytool -list -keystore /path/to/elasticsearch/config/truststore.jks -storepass your_password
       
    # 导入缺失的 CA 证书(如果需要)
    keytool -import -alias idp-ca -file /path/to/idp-ca.crt -keystore /path/to/elasticsearch/config/truststore.jks
    
  5. 检查身份提供方配置:确认 IdP 的 UserInfo Endpoint 是否需要特定 scope,避免 token 能换到但 UserInfo 无法访问。

  6. 检查性能和可用性:如果只在高峰期触发,检查连接池、线程池和上游身份服务限流情况。

排查时需要注意的问题 #

  • 不要只看 Failed to get claims 这个表层错误,一定要找到 Caused by 部分的根本异常,才能确定是网络、TLS 还是服务可用性问题。
  • OIDC 认证涉及多个步骤(授权码交换、token 验证、claims 获取),需要区分失败发生在哪个阶段。
  • 如果使用 Docker 或 Kubernetes 部署 Elasticsearch,需要注意容器网络的 DNS 解析和出口策略。

4. 如何解决这个错误 #

常用修复思路 #

  • 修正 UserInfo Endpoint 地址:核对并修正 op.userinfo_endpoint 配置,确保地址正确且可访问。

    # elasticsearch.yml 中的 OIDC Realm 配置示例
    xpack.security.authc.realms.oidc.oidc1:
      order: 2
      rp.client_id: "your-client-id"
      rp.response_type: "code"
      op.issuer: "https://your-idp-domain.com"
      op.authorization_endpoint: "https://your-idp-domain.com/oauth2/authorize"
      op.token_endpoint: "https://your-idp-domain.com/oauth2/token"
      op.userinfo_endpoint: "https://your-idp-domain.com/oauth2/userInfo"  # 确保此地址正确
      op.jwkset_path: "https://your-idp-domain.com/oauth2/jwks"
    
  • 修复 TLS 信任链:为 Elasticsearch 节点补全正确的 CA 证书或修复 TLS 信任链。

    # 配置 SSL 信任库
    xpack.security.authc.realms.oidc.oidc1:
      ssl.truststore.path: "/path/to/truststore.jks"
      ssl.truststore.password: "truststore_password"
      ssl.truststore.type: "JKS"  # 或 PKCS12
    
  • 调整超时设置:如果底层异常是超时,适当调大 HTTP 超时时间。

    xpack.security.authc.realms.oidc.oidc1:
      http.connect_timeout: "10s"  # 默认可能较小,适当调大
      http.socket_timeout: "30s"
      http.max_connections: 50
      http.max_endpoint_connections: 10
    
  • 解决身份服务不可用问题:如果 IdP 服务本身不稳定,先解决上游可用性问题,再验证登录流程。

  • 配置代理(如果需要):如果 Elasticsearch 需要通过代理访问外部 IdP,配置 HTTP 代理。

    xpack.security.authc.realms.oidc.oidc1:
      http.proxy.host: "proxy.example.com"
      http.proxy.port: 3128
    

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

  • 为 OIDC 认证配置合理的重试和降级策略,避免 IdP 短暂不可用导致所有用户无法登录。
  • 定期检查和更新 IdP 的证书,避免因证书过期导致认证中断。
  • 在 Elasticsearch 和 IdP 之间配置健康检查,及时发现连通性问题。
  • 为认证相关错误配置专门的监控和告警,确保在用户受影响前发现问题。

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

  • INFINI Console 适合查看集群的安全配置、认证日志和用户访问趋势,帮助快速判断 OIDC 认证失败的影响范围和频率,并提供可视化的配置管理和审计功能。
  • INFINI Gateway 适合部署在 Elasticsearch 前面做请求观测和流量治理,可以记录所有认证相关请求的详细日志,帮助定位 OIDC 流程中具体哪个环节出现问题,同时提供缓存和重试机制来提升认证稳定性。
  • 建议将 OIDC 认证日志统一接入监控面板,结合 INFINI Console 的告警功能,在认证失败率上升时及时通知管理员。

5. 小结 #

Failed to get claims from the Userinfo Endpoint. 说明失败点落在"向 OIDC Provider 发请求取 claims"这一步。最重要的是抓到底层异常,区分是网络/TLS 故障,还是身份服务本身不可用。大多数情况下,这个问题可以通过检查 Caused by 异常、验证 IdP 连通性和修复 TLS 配置来解决。

只要把 OIDC 配置校验、证书管理和连通性监控固定下来,大多数认证类异常都可以被快速定位和恢复,也更容易通过 INFINI Console 和 INFINI Gateway 实现持续防护。

相关错误 #

参考文档 #

附:日志上下文 #

下面保留当前页面中的源码或日志片段,便于继续结合异常调用栈定位问题:

}  @Override
    public void failed(Exception ex) {
        claimsListener.onFailure(
            new ElasticsearchSecurityException("Failed to get claims from the Userinfo Endpoint."; ex)
        );
    }  @Override
    public void cancelled() {