authSource 决定去哪校验
MongoDB 的用户是「在哪个库创建,就由哪个库校验密码」,这个库叫认证库,连接串里的 authSource 参数就是指定它的位置。如果连接串不写 authSource,驱动会默认拿连接串路径中的库名当认证库,而账号实际建在别的库时就会直接返回 Authentication failed,这是排查连不上问题时最先要确认的一项。
基本信息
| 认证库规则 | 用户在哪个库创建就由哪个库完成认证 |
|---|---|
| 默认取值 | 未写 authSource 时取连接串路径中的库名 |
| 显式指定 | mongodb://user:pwd@host:27017/app?authSource=admin |
| 会话内认证 | db.auth("user", "pwd"),返回 1 表示成功 |
| 认证机制 | SCRAM-SHA-256 为默认,老客户端可临时建 SCRAM-SHA-1 账号过渡 |
典型使用场景
- 运维账号建在 admin 库,业务代码连业务库时必须显式带 authSource=admin
- 多租户环境每个业务库各自建账号,认证库与业务库同名时可省略该参数
- 手工排查连接问题时用 db.auth 区分是账号问题还是网络可达性问题
- 从旧驱动或旧版本迁移时,处理认证机制协商失败导致的登录失败
- 盘点账号归属,确认连接串写法与账号实际创建位置一致
认证写法与验证
认证写法与验证
# 账号建在 admin,业务库是 app:必须指定 authSource
mongosh "mongodb://ops:secret@127.0.0.1:27017/app?authSource=admin"
# 账号就建在 app 库:认证库与业务库同名,可省略 authSource
mongosh "mongodb://app:secret@127.0.0.1:27017/app"
# 已进入 shell 后手工认证,返回 1 表示成功、0 表示失败
mongosh "mongodb://127.0.0.1:27017/app"
db.auth("ops", "secret") # 1 = 成功,0 = 失败
# 查看当前会话的身份与已授权用户
db.runCommand({ connectionStatus: 1 })认证失败排查顺序
| 现象 | 可能原因 | 处理方向 |
|---|---|---|
| Authentication failed | authSource 指向的库里没有该用户 | 补上 authSource=admin,或改用认证库下的账号 |
| Authentication failed 且密码确认无误 | 密码中的 @ : / 等字符未做 URL 编码 | 对特殊字符做百分号编码后重试 |
| 机制协商失败 | 老驱动只支持 SCRAM-SHA-1 | 优先升级驱动,过渡期可临时建兼容账号 |
| not authorized on app | 认证已通过但缺少该库的角色 | 在用户所属库授予对应 readWrite 角色 |
认证库与授权库是两个概念:账号可以认证在 admin,同时被授予 app 库的读写角色。排查 not authorized 时要看角色授权范围,反复修改 authSource 并不能解决问题。