spring boot 2.x 连接 mongodb 5.0 报 unauthorized 错误,根本原因是认证三要素未对齐:服务端必须启用 authorization 并在 admin 库用 scram-sha-256 创建用户,客户端连接字符串须显式指定 authsource=admin 和 authmechanism=scram-sha-256,且驱动版本不低于 4.4。

Spring Boot 2.x 连接 MongoDB 5.0 报错 Unauthorized,基本就是认证配置没对上——不是密码错了,而是服务端机制、客户端参数、连接字符串三者没对齐。
authSource 必须显式指定,不能省略
MongoDB 5.0 不再默认去 admin 库查用户凭证。哪怕你用的是 admin 用户,也得在连接串里写明 authSource=admin,否则服务端直接拒绝认证。
- 错误写法:
mongodb://svc-app:pass@localhost:27017/myapp(缺authSource) - 正确写法:
mongodb://svc-app:pass@localhost:27017/myapp?authSource=admin - Spring Boot 配置中漏掉这个参数,
spring.data.mongodb.uri就算用户名密码都对,照样报error 13 (Unauthorized) - Robo 3T / Compass 的 “Authentication Database” 字段必须填
admin,留空或填目标库名(如myapp)都会失败
用户必须在 admin 库创建,且 mechanisms 显式设为 SCRAM-SHA-256
MongoDB 4.x 创建的用户默认是 SCRAM-SHA-1 格式,5.0 默认只接受 SCRAM-SHA-256,旧用户不兼容。
- 建用户时必须加
mechanisms: ["SCRAM-SHA-256"],例如:db.createUser({user:"svc-app", pwd:"xxx", roles:[{role:"readWrite", db:"myapp"}], mechanisms:["SCRAM-SHA-256"]}) -
mechanisms只在createUser时生效,db.changeUserPassword()不会升级哈希算法 - 别在业务库(如
myapp)里建用户——那样就得配authSource=myapp,但 Spring Boot 默认不查那里,容易绕晕 - 确认是否启用授权:
db.runCommand({getParameter: 1, authorization: 1})返回authorization: true才算生效
驱动版本和 authenticationMechanism 参数要匹配
Spring Boot 2.5.x 自带的 MongoDB Java 驱动是 4.2.x,而 5.0 要求至少 4.4+ 才能协商 SCRAM-SHA-256。旧驱动可能 fallback 到不支持的机制,握手直接失败。
- 升级依赖:
org.mongodb:mongodb-driver-sync:4.11.0+(对应 Spring Boot 2.7+ 自带) - 连接串里可显式指定机制:
?authMechanism=SCRAM-SHA-256,避免自动协商出错 - Go / Python 等其他语言客户端也要检查驱动版本,比如 PyMongo 4.0+ 才默认启用 SHA-256
- Docker 初始化用户注意:
MONGO_INITDB_ROOT_USERNAME环境变量只在首次启动时生效;已初始化过的容器,这些变量无效,必须进 shell 手动建用户
副本集 keyFile 权限和主机名要求更严格
5.0 副本集启动时会对 keyFile 做硬性校验,同时强制要求成员使用 DNS 主机名,IP 地址会被拒绝。
-
chmod 400 /etc/mongo-keyfile是唯一被接受的权限,600或644都会启动失败 - keyFile 属主必须是运行
mongod的用户(如mongod),不能是root -
rs.initiate()中所有members.host必须是可解析的 DNS 名(如node1.example.com:27017),不能是192.168.1.10:27017 - SELinux/AppArmor 会静默拦截 keyFile 读取,即使权限和属主都对,也要检查安全模块是否放行
最常被忽略的其实是顺序:先改配置启用 authorization: enabled 并重启 mongod,再连本地建用户;顺序反了,或者只 reload 没 restart,都会卡在“有授权但无用户”的状态,连都连不上。











