遇到 Kafka 客户端报 AuthenticationException,通常是因为安全协议配置不一致或凭证错误,优先检查客户端的安全协议配置是否与 Broker 端匹配。
先说结论:这是一个配置对齐问题,绝大多数情况是客户端缺少必要的 SASL 或 SSL 参数,或者密码包含特殊字符未转义。
- 先确认 Broker 端启用的安全协议类型(PLAIN、SCRAM 或 SSL)。
- 先处理客户端配置文件中的 JAAS 配置项和信任库路径。
- 再验证使用命令行工具能否绕过代码逻辑直接连通。
命令速用版
如果你手头有 Kafka 安装包,可以用官方自带的命令行工具快速测试连通性,排除代码逻辑干扰:
kafka-console-consumer.sh `--bootstrap-server` <host>:9092 `--topic` <topic> `--consumer`.config client.properties
其中 client.properties 需要包含安全配置,例如:
security.protocol=SASL_PLAINTEXT
sasl.mechanism=PLAIN
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username="user" password="pass";
关键错误日志解读
出现 AuthenticationException 时,客户端日志通常包含具体的 SASL 或 SSL 握手失败信息。以下是典型日志片段:
org.apache.kafka.common.errors.SaslAuthenticationException: Authentication failed: Invalid username or password
Caused by: javax.security.sasl.SaslException: Authentication failed: Invalid username or password
如果看到 Invalid username or password,重点检查 JAAS 配置中的用户名密码;如果看到 SSLHandshakeException,则重点检查证书信任库。
分步处理与配置对照
1. 核对安全协议
检查 Broker 的 server.properties 中 listeners 配置。如果监听器是 SASL_PLAINTEXT,客户端 security.protocol 必须对应设置,不能留空或写成 PLAINTEXT。
2. 不同认证机制配置示例
根据 Broker 端配置,客户端需匹配相应的机制。以下是常见配置对照:
- SASL/PLAIN:适用于内网测试,密码明文传输。
security.protocol=SASL_PLAINTEXT
sasl.mechanism=PLAIN
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username="admin" password="admin-secret";
- SASL/SCRAM-SHA-256:适用于生产环境,密码哈希存储。
security.protocol=SASL_PLAINTEXT
sasl.mechanism=SCRAM-SHA-256
sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username="admin" password="admin-secret";
- SSL/TLS:需要证书文件。
security.protocol=SSL
ssl.truststore.location=/var/private/ssl/client.truststore.jks
ssl.truststore.password=test1234
3. 检查 JAAS 配置细节
sasl.jaas.config 的语法非常严格,末尾的分号不能少。用户名和密码如果用变量替换,要注意转义。如果是 SCRAM 机制,确保用户名大小写敏感。
Spring Boot 集成示例
在 Spring Boot 项目中,通常在 application.yml 中配置 Kafka 安全参数:
spring:
kafka:
bootstrap-servers: <host>:9092
properties:
security.protocol: SASL_PLAINTEXT
sasl.mechanism: PLAIN
sasl.jaas.config: org.apache.kafka.common.security.plain.PlainLoginModule required username="user" password="pass";
注意:在 YAML 文件中,如果密码包含特殊字符(如冒号、井号),建议使用引号包裹整个 JAAS 字符串。
怎么验证是否生效
1. 观察客户端日志,AuthenticationException 消失且不再重连。
2. 查看 Broker 端日志,确认没有相关的认证失败记录。
3. 对于 SSL 配置,可使用 openssl 命令验证证书链路(非纯 TCP 连通性):
openssl s_client -connect <host>:9093 -showcerts
如果能看到 Certificate chain 信息,说明 SSL 握手层面基本正常。
常见坑
1. 密码中包含特殊字符(如 @、#)时,在配置文件里可能需要转义,但在 JAAS 字符串里有时不需要,具体取决于加载方式。
2. 客户端时间与服务端时间偏差过大,会导致 SSL 握手失败,表现为认证异常。
3. 多个监听器混用,客户端连错了端口,比如连到了未开启鉴权的端口却配了鉴权参数,或者反之。
4. telnet 只能测试 TCP 端口连通性,无法验证应用层认证,认证失败时 telnet 可能依然是通的。