同一用户不能混用 SCRAM-SHA-1 和 SCRAM-SHA-256,因二者哈希格式互斥、凭证独立,MongoDB 强制单机制绑定;切换需重设密码或新建用户,不可叠加或共存。

同一用户不能混用 SCRAM-SHA-1 和 SCRAM-SHA-256
不能。MongoDB 明确禁止对同一用户同时启用两种 SCRAM 机制——SCRAM-SHA-1 和 SCRAM-SHA-256 是互斥的认证方式,底层密码哈希存储格式完全不同,数据库在验证时只认其中一种。
- 一个用户创建时指定
SCRAM-SHA-256,其密码哈希就以 SHA-256 摘要形式存入admin.system.users;换成SCRAM-SHA-1后,旧哈希无效,必须重设密码 - 如果你在 Ops Manager 或 mongosh 中反复切换
scramIterationCount或修改mechanism参数试图“升级”,实际只会覆盖或报错,不会共存 - 错误现象常见于迁移场景:比如用
db.createUser(..., {mechanisms: ["SCRAM-SHA-256"]})创建用户后,又执行db.updateUser(..., {mechanisms: ["SCRAM-SHA-1"]})—— 这会直接删掉原 SHA-256 凭证,不是叠加
为什么必须选一种?看密码存储和协议差异
SCRAM 不是“开关式配置”,而是绑定到每个用户的凭证实体。SHA-1 和 SHA-256 对应两套独立的盐值(salt)、迭代次数、摘要结构,服务器无法用一套逻辑验证两种哈希。
-
SCRAM-SHA-1基于 RFC 5802,使用 4096 次迭代(默认),但 FIPS 模式下被禁止 -
SCRAM-SHA-256基于 RFC 7677,迭代数默认 15000+,安全性更高,且是 FIPS 合规唯一支持的 SCRAM 变体 - 客户端驱动(如 Node.js 的
mongodb包)连接时若未显式指定authMechanism,会按服务端返回的supportedMechanisms自动协商——但前提是该用户只注册了一种机制
升级时最容易踩的坑:误以为“加个机制就行”
很多团队想平滑过渡到 SCRAM-SHA-256,结果在生产环境执行了错误操作,导致用户瞬间失联。
- ❌ 错误做法:对已有
SCRAM-SHA-1用户调用db.updateUser()并追加"SCRAM-SHA-256"到mechanisms数组 —— MongoDB 会拒绝该请求,报错Cannot specify multiple SCRAM mechanisms for a user - ✅ 正确路径:新建用户(用
SCRAM-SHA-256),验证连接无误后,再删旧用户;或用db.changeUserPassword()+ 显式mechanism: "SCRAM-SHA-256"强制重置(这会覆盖原有哈希) - ⚠️ 注意:MongoDB 4.0+ 已彻底弃用
MONGODB-CR,如果你还在用老用户,必须先升级到任意一种 SCRAM,不能跳过
连接字符串和驱动里怎么指定机制?
绝大多数现代驱动默认协商,但显式声明更稳妥,尤其在混合部署或调试时。
- mongosh 连接:
mongosh "mongodb://user:pass@host:27017/admin?authMechanism=SCRAM-SHA-256" - Node.js 驱动:
new MongoClient(uri, { authMechanism: "SCRAM-SHA-256" }) - Python PyMongo:
client = MongoClient(..., authMechanism="SCRAM-SHA-256") - 不指定时,驱动会发
saslStart请求探查服务端支持项;但如果用户只存了 SHA-256 凭证,而驱动因兼容性 fallback 到 SHA-1,就会认证失败——这个静默 fallback 很容易被忽略
真正麻烦的不是选哪个机制,而是所有相关方(Ops Manager、备份脚本、监控 Agent、应用配置)是否同步更新了对应用户的凭证和连接参数。一个地方漏改,就卡在 Authentication failed 里查半天。

















