Unauthorized 13 错误表示已连接但认证失败,核心排查点是服务端真实认证状态、authSource是否匹配用户所在库(如admin)、以及驱动与服务器认证机制是否兼容(如SCRAM-SHA-256)。

Unauthorized 13 错误不是“连不上”,而是“连上了但没过审”——它明确表示 MongoDB 接收了连接请求,也收到了操作命令(比如 insert、listDatabases),但拒绝执行,因为认证环节失败或缺失。排查必须从服务端真实配置出发,而不是只看本地 config 文件是否写了 authorization: enabled。
查服务端是否真启用了认证
很多人以为注释掉 mongod.conf 里的 security.authorization 就等于关了认证,其实未必。MongoDB 启动时可能加载了多个配置片段(比如通过 include 引入 /etc/mongod/conf.d/01-auth.yml),也可能被云服务控制台策略覆盖。
- 进 shell 执行
db.adminCommand({ getCmdLineOpts: 1 }),重点看parsed.security.authorization字段值是不是true—— 这才是运行时真实状态 - 云数据库(如 Atlas、阿里云 MongoDB)默认开启访问控制,本地配置无效;必须去控制台确认「白名单」和「认证方式」
- 如果用 Docker,检查容器启动时是否传了
--auth或设置了MONGO_INITDB_ROOT_USERNAME等环境变量,这些会强制启用认证
检查连接字符串里 authSource 是否匹配用户所在库
这是 Spring Boot 和 Navicat 用户踩坑最密集的地方:authSource 不是目标数据库,而是“存用户名密码的库”。默认不写,MongoDB 就去你指定的数据库(比如 mongodb://u:p@h:27017/mydb 中的 mydb)查用户,而实际用户往往建在 admin 库里。
- 正确写法(用户在 admin 库):
mongodb://user:pass@localhost:27017/mydb?authSource=admin - 错误写法:
mongodb://user:pass@localhost:27017/mydb(默认去mydb查用户,找不到 → Unauthorized) - 更隐蔽的错:
mongodb://user:pass@localhost:27017/mydb?authSource=mydb(指定了错误的 authSource,仍找不到) - Node.js 驱动中若误设
authMechanism: 'DEFAULT'且没传凭据,驱动会主动发 AUTH 请求,直接触发 Unauthorized
区分真实攻击和本地误连
日志里频繁出现 Unauthorized,IP 却是 127.0.0.1 或内网段(如 10.0.0.x),大概率不是黑客,而是你自己服务的探活或监控在失败重试。
- Prometheus 的
mongodb_exporter默认用空凭据连admin,会立即报 Unauthorized - K8s 的 readiness probe 如果配了错误密码,会在几秒内反复连接又断开
- Docker Compose 中应用容器启动时硬编码了旧密码,也会持续失败
- 用
sudo tcpdump -i any port 27017 -w mongod.pcap抓包,Wireshark 过滤mongo.opcode == 2004(AUTH 操作),能精准定位来源进程
权限不足和认证机制不匹配常被混为一谈
同样是 Unauthorized 13,原因可能是用户没角色,也可能是驱动和服务器“说不上话”。MongoDB 5.0+ 默认禁用老旧的 MONGODB-CR,只接受 SCRAM-SHA-256;而 Spring Boot 2.5.x 自带的驱动版本(4.2.x)默认协商 SCRAM-SHA-1,握手失败后服务端直接拒掉连接。
- 检查驱动版本:Spring Boot 2.7+ 推荐显式升级到
org.mongodb:mongodb-driver-sync:4.11+ - 强制指定机制(必要时):
?authMechanism=SCRAM-SHA-256 - 创建用户时注意机制兼容性:用
db.createUser(..., { mechanisms: ['SCRAM-SHA-256'] })显式声明 - 权限不足的表现是连接成功、部分操作失败(比如能
find但不能insert),这时要查db.getUser('xxx')确认角色是否包含readWrite或更高
最容易被忽略的是:MongoDB 对 localhost 连接有特殊信任逻辑(允许先连后 auth),但所有图形工具、远程客户端、K8s 容器内访问都走标准认证流程——这意味着你在终端能连通,不代表 Navicat 或 Spring Boot 就能通。别跳过 authSource 和真实运行态配置验证这两步。

















