Kafka 4.4.0 起,Broker 配了 SASL/OAUTHBEARER 的 JWKS 地址却没写 expected.audience / expected.issuer,进程会直接 ConfigException 拒启。4.3.1 同配置只打 WARN,照样 Kafka Server started。对应官方 CVE 列表里的 CVE-2026-110952(2026-10-28 公告)。

场景很常见:升到 4.4.0 之后 Broker 起不来,日志里全是 OAuth validator 抱怨 audience。不是磁盘格式问题(那是另一篇 Kafka 4.4.0 存储回退 的故事),而是安全默认值收紧了。

问题从哪来

开了 sasl.oauthbearer.jwks.endpoint.url 时,签名校验一直有。但 iss / aud 一直是可选的:不配就跳过。多租户 IdP、共享 JWKS 时,别的 issuer 签出来的令牌也可能被当成合法身份。官方 CVE 列表把修复只放进了 4.4.0:有 JWKS 就必须同时配齐 expected issuer 与 audience,否则拒绝启动。

同日还有 CVE-2026-110985(未配 JWKS 时静默回落不验签)。那条在 4.3.1 已修。本文只对照 已配 JWKS、未配 audience/issuer 这一条启动行为,不碰令牌伪造。

最小对照怎么搭

两套独立进程:Apache Kafka 4.3.1 与 4.4.0,KRaft 单节点,Java 21.0.12.1。客户端监听用 SASL_PLAINTEXT + OAUTHBEARER,控制器与 broker 间通信仍走 PLAINTEXT,避免为了验启动行为再去配 client login。JWKS 用本地空 keys 文件,并设置:

-Dorg.apache.kafka.sasl.oauthbearer.allowed.urls=file:///.../jwks/keys.json

关键配置(两边相同,4.4.0「修好能启」那组会再补两行):

sasl.enabled.mechanisms=OAUTHBEARER
listener.name.sasl_plaintext.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required;
listener.name.sasl_plaintext.oauthbearer.sasl.server.callback.handler.class=org.apache.kafka.common.security.oauthbearer.OAuthBearerValidatorCallbackHandler
listener.name.sasl_plaintext.oauthbearer.sasl.oauthbearer.jwks.endpoint.url=file:///.../jwks/keys.json
# 故意不写 expected.issuer / expected.audience

4.3.1:只警告,照样起来

同配置启动 4.3.1,日志先警告缺 audience、缺 issuer,随后进入 STARTED:

[2026-10-31 08:15:41,951] WARN The OAuth broker validator is configured with a JWKS endpoint but without "sasl.oauthbearer.expected.audience", so it will accept a JWT that does not carry an "aud" (audience) claim. This is strongly discouraged; set "sasl.oauthbearer.expected.audience" to the audience(s) your brokers expect so that the token audience is verified. (org.apache.kafka.common.security.oauthbearer.BrokerJwtValidator)
[2026-10-31 08:15:41,951] WARN The OAuth broker validator is configured with a JWKS endpoint but without "sasl.oauthbearer.expected.issuer", so it will accept a JWT bearing any (or no) "iss" (issuer) claim. This is strongly discouraged; set "sasl.oauthbearer.expected.issuer" to the issuer URL of your OAuth/OIDC provider so that the token issuer is verified. (org.apache.kafka.common.security.oauthbearer.BrokerJwtValidator)
[2026-10-31 08:15:42,391] INFO [BrokerServer id=1] Transition from STARTING to STARTED (kafka.server.BrokerServer)
[2026-10-31 08:15:42,394] INFO [KafkaRaftServer nodeId=1] Kafka Server started (kafka.server.KafkaRaftServer)

进程活着。生产里如果只扫 ERROR,这两条 WARN 很容易漏掉。

4.4.0:缺 audience,启动即挂

同一份「只开 JWKS、不写 audience/issuer」的配置,4.4.0 在配置阶段直接抛 ConfigException,Broker 记 Fatal 后退出:

[2026-10-31 08:15:39,573] WARN The class org.apache.kafka.common.security.oauthbearer.DefaultJwtValidator defined in the sasl.oauthbearer.jwt.validator.class configuration encountered an error on configure(): The OAuth validator for the broker requires "sasl.oauthbearer.expected.audience" to be configured so that the token's audience ("aud") claim can be verified, but it was not set. Set "sasl.oauthbearer.expected.audience" to the audience(s) that identify this cluster, or set "sasl.oauthbearer.allow.unverified.audience" to true to accept tokens regardless of their audience. (org.apache.kafka.common.security.oauthbearer.internals.secured.ConfigurationUtils)
org.apache.kafka.common.config.ConfigException: The OAuth validator for the broker requires "sasl.oauthbearer.expected.audience" to be configured so that the token's audience ("aud") claim can be verified, but it was not set. Set "sasl.oauthbearer.expected.audience" to the audience(s) that identify this cluster, or set "sasl.oauthbearer.allow.unverified.audience" to true to accept tokens regardless of their audience.
[2026-10-31 08:15:39,575] ERROR [BrokerServer id=1] Fatal error during broker startup. Prepare to shutdown (kafka.server.BrokerServer)

没有 Kafka Server started。升完 4.4.0 起不来,先查这两行,别先怀疑 Kraft 元数据。

配齐之后 4.4.0 能起来

在同一 listener 上补上 issuer 与 audience(值换成你们 IdP 的真实 iss / 集群约定的 aud):

listener.name.sasl_plaintext.oauthbearer.sasl.oauthbearer.expected.issuer=https://idp.example.com
listener.name.sasl_plaintext.oauthbearer.sasl.oauthbearer.expected.audience=kafka-cluster

再启 4.4.0:

[2026-10-31 08:15:57,309] INFO [KafkaRaftServer nodeId=1] Kafka Server started (kafka.server.KafkaRaftServer)

官方也允许按轴显式放弃校验:sasl.oauthbearer.allow.unverified.issuer=true / allow.unverified.audience=true。那是逃生口,不是默认。

和 Spring 侧怎么衔接

Broker 拒启是服务端行为,跟 Spring Boot / spring-kafka 版本无直接绑死。业务若已经在用 OAUTHBEARER 连 Broker,升 4.4.0 前先把 listener 上的 expected.issuer、expected.audience 写进配置模板;客户端令牌的 iss/aud 要和这两项对得上,否则以后是认证失败,而不是静默放行。

仍停在 4.3.x 的集群,至少把这两项配上,别只靠 WARN。4.4.0 只是把「强烈不建议」改成了「起不来」。

版本与许可

对照二进制:kafka_2.13-4.3.1.jar / kafka_2.13-4.4.0.jar。许可证 Apache License 2.0。仓库 apache/kafka。公告与修复说明见 Kafka CVE List 中 CVE-2026-110952 条目。

— 感谢阅读 —
广告

一起交流

分享你的思考,让讨论更进一步。