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

适用版本: 7.x-8.x 涉及组件: OpenID Connect Realm、JWT Realm、Elasticsearch 安全模块

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

missing required date claim [claimName] 是 Elasticsearch 在安全认证阶段抛出的异常,表示在解析 JWT / OIDC Token 或 UserInfo 时,某个被标记为必需日期类型声明不存在或值为空。

该异常属于 ElasticsearchSecurityException,通常发生在用户尝试登录、令牌刷新或角色映射解析的过程中。

常见现象 #

  • 用户无法通过 OIDC / JWT 方式登录 Elasticsearch 或 Kibana,页面直接报错或跳转回登录页。
  • 在 Elasticsearch 日志中可以看到类似下面的异常信息:
ElasticsearchSecurityException[missing required date claim [exp]]
    at org.elasticsearch.xpack.security.authc.oidc.OpenIdConnectAuthenticator...
  • 不同用户表现不一致:部分用户能正常登录,另一部分用户报错,可能与 IdP 中用户属性或租户配置有关。
  • 若使用了 Elasticsearch 作为 Kibana 的后端认证,Kibana 启动后也可能因后台定时令牌校验失败而反复出现该错误。

典型报错与异常栈 #

以下日志片段是该异常在源码中的直接抛出位置:

if (claimValue == null) {
    throw new ElasticsearchSecurityException("missing required date claim [" + claimName + "]");
}

可以看到,该异常不依赖日期解析失败,而是在声明值为 null 时直接抛出,说明问题核心是"字段不存在"而非"字段格式错误"。

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

Elasticsearch 的 OIDC Realm 和 JWT Realm 支持通过 claims.*populate_user_metadata 等配置将 Token 中的声明映射为用户的属性或元数据。当某个声明被配置为 required: true,且声明类型为日期时,Elasticsearch 会在认证流程中强制校验该字段是否存在。

常见原因包括:

  • IdP 未签发该声明:例如配置了 required date claim [auth_time],但 IdP 的 Token 中并未包含 auth_time 字段。
  • claim 名称配置错误:Elasticsearch 中配置的 claim 名称与 IdP 实际返回的字段名不一致(大小写敏感、拼写错误、嵌套路径错误等)。
  • scope 不足导致声明未返回:OIDC 中某些声明只有在请求特定 scope(如 profileemail)时才会被包含在 ID Token 或 UserInfo 中。
  • 用户类型或租户差异:IdP 对不同用户类型(如企业用户 vs 社交登录用户)返回的声明集合不同,部分用户缺少该字段。
  • Token 类型混淆:使用了 Access Token 而非 ID Token,而 Access Token 中并不包含该日期声明。
  • Elasticsearch 配置升级后未同步:升级后新增了 required 约束,但 IdP 侧的 Token 结构未做相应调整。

3. 如何排查这个异常 #

建议按"先确认 Token 内容,再核对配置"的顺序处理:

  1. 获取完整的 Token 内容

    • 在浏览器开发者工具或网络抓包中,找到 id_token 字段。
    • 将 JWT Token 粘贴到 jwt.io 解码,查看 payload 中是否包含目标声明。
    • 如果是 OIDC 流程,同时检查 /userinfo 端点的返回内容。
  2. 核对 Elasticsearch realm 配置

    • 打开 elasticsearch.yml,找到对应的 OIDC / JWT realm 配置。
    • 确认 claims.*.requiredrequired_claims 中是否将该日期声明标记为必需。
    • 注意 claim 名称的大小写和嵌套路径(如 claims.exp.required: true)。
  3. 检查 IdP 的 Token 签发规则

    • 登录 IdP 管理后台(如 Keycloak、Okta、Auth0、Azure AD 等)。
    • 查看对应 Client / Application 的 Mapper 配置,确认目标声明是否被正确映射。
    • 检查是否仅为特定用户组或协议类型启用了该声明。
  4. 对比正常与异常用户的 Token

    • 用两个不同账号分别登录,解码两份 Token,对比声明集合的差异。
    • 重点关注 expiatauth_timenbf 等常见日期声明。
  5. 查看 Elasticsearch 日志上下文

    • 搜索日志中 missing required date claim 前后的完整异常栈,确认是哪个 realm 抛出的异常。

排查时需要注意的问题 #

  • 不要只看成败结果:Token 解码后的完整声明列表才是判断依据,不能仅凭"其他用户能登录"就排除 IdP 配置问题。
  • 注意 Token 类型:OIDC 流程中的 id_tokenaccess_token 内容不同,Elasticsearch 默认校验的是 id_token
  • 时间单位问题:JWT 中的日期声明通常为 Unix 时间戳(秒),若 IdP 返回的是毫秒或其他格式,也可能导致间接缺失(被解析为 null)。

4. 如何解决这个错误 #

常用修复思路 #

方案一:在 IdP 侧补充缺失的日期声明

以 Keycloak 为例,进入 Client → Mappers → Add Mapper,新建一个 Token Mapper:

Mapper Type: Hardcoded claim / Script Mapper
Token Claim Name: auth_time
Claim JSON Type: long
Claim value: ${context.timestamp}

对于 Auth0,可在 Rules 或 Actions 中添加:

exports.onExecutePostLogin = async (event, api) => {
  api.idToken.setCustomClaim('auth_time', Math.floor(Date.now() / 1000));
};

方案二:修正 Elasticsearch 中的 claim 配置

如果确认 IdP 不会返回该声明,可以将其从 required 列表中移除。编辑 elasticsearch.yml

xpack.security.authc.realms.oidc.oidc1:
  order: 1
  claims:
    auth_time:
      required: false   # 改为 false 或删除 required 配置

修改后执行:

POST _security/realm/oidc1/_reload

或直接重启 Elasticsearch 节点使配置生效。

方案三:调整 scope 配置

在 Elasticsearch realm 配置中补充所需的 scope:

xpack.security.authc.realms.oidc.oidc1:
  scopes: ["openid", "profile", "email"]

方案四:统一 Token 类型

确认 Kibana 和 Elasticsearch 使用的都是 id_token,而非仅使用 access_token 做认证。

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

  • 在 IdP 侧为所有关键日期声明(expiatnbf)设置默认值或 fallback 逻辑,避免因声明缺失导致大范围登录失败。
  • 对 OIDC / JWT realm 配置做变更前,先在测试环境用真实 Token 验证,确认所有 required 声明均可正常返回。
  • 建立 Token 声明的一致性检查机制,在 IdP 侧新增 Mapper 或改动 Scope 后,及时同步 Elasticsearch 侧的 realm 配置。
  • 在 Kibana 中配置多个 realm 作为备用认证方式,避免单一 OIDC 配置故障导致全部用户无法登录。

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

  • INFINI Console 适合查看 Elasticsearch 集群的安全配置、认证日志和用户访问趋势,帮助快速判断异常是 Token 问题还是集群配置问题。
  • INFINI Gateway 部署在 Elasticsearch 前面,可以对认证请求做深度观测,捕获完整的 Token 内容和请求头信息,无需直接翻看 Elasticsearch 源码日志即可定位声明缺失问题。
  • 建议将 OIDC / JWT 认证失败日志统一接入监控面板,按 realm、用户、错误类型做分类统计,缩短从"发现登录失败"到"定位缺失声明"的时间。

5. 小结 #

missing required date claim [claimName] 的核心原因是 Elasticsearch 在认证流程中要求某个日期声明必须存在,但实际 Token 中并没有该字段。排查时应优先解码 Token 确认声明是否存在,再核对 Elasticsearch realm 配置与 IdP 签发规则是否一致。只要保证"配置声明的名称"与"IdP 实际返回的字段"完全匹配,并确保 required 配置与实际签发能力相符,该问题即可彻底解决。

相关错误 #

附:日志上下文 #

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

if (claimValue == null) {
    throw new ElasticsearchSecurityException("missing required date claim [" + claimName + "]");
}