mongodb容器默认无认证,修复需先启用认证再创建用户;有数据时须手动建用户并重启容器;客户端连接字符串必须指定authsource=admin。

容器化部署的 MongoDB 默认不开启认证,不是疏忽,而是设计使然:Docker 镜像启动时若未显式启用 --auth 或配置 security.authorization: enabled,服务就以“无认证模式”运行——此时任何能连到端口的客户端,都可读写任意数据库。修复必须分两步走:先确保认证机制启用,再创建有效用户;漏掉任一环节,等于没修。
确认当前容器是否真的在无认证模式下运行
别只看启动命令里有没有 --auth,实际状态得靠验证。很多用户改了 docker-compose.yml 却没重建容器,或误以为环境变量 MONGO_INITDB_ROOT_USERNAME 自动触发了认证。
- 执行
docker exec -it <container> mongosh --eval "db.runCommand({getCmdLineOpts: 1})"</container>,检查输出中parsed.security.authorization是否为true - 直接连进去不输密码:
docker exec -it <container> mongosh admin</container>,如果成功进入且能执行db.getUsers()返回空数组,说明认证已启用但无用户;如果连进去就能随便use mydb; db.coll.insertOne({...}),那就是认证根本没开 - 注意:
MONGO_INITDB_ROOT_USERNAME等变量仅在/data/db为空时生效;已有数据的容器重启后,这些变量完全被忽略
修复方式取决于容器是否已初始化数据
这是最容易卡住的地方。有数据和没数据,修复路径完全不同,强行套用会失败。
- 容器首次启动、
/data/db是空的:删掉容器 + 清空 volume,用带--auth和环境变量的命令重跑。例如:docker run -d --name mongo -p 27017:27017 -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=123456 mongo:7 --auth - 容器已运行多日、数据不能丢:必须进容器手动建用户。先停掉应用连接,再执行:
docker exec -it <container> mongosh --host 127.0.0.1 --port 27017</container>(用127.0.0.1绕过本地 socket 认证限制),切到admin库,运行db.createUser({user:"svc", pwd:"xxx", roles:[{role:"readWrite", db:"myapp"}]}) - 切记:建完用户后,必须重启 mongod 进程才能强制认证生效——不是 reload,是
docker restart <container></container>。否则旧连接仍保持未认证状态
连接字符串里漏掉 authSource=admin 就等于没设密码
90% 的“连不上”问题其实不是认证没开,而是客户端根本没去对的地方找凭证。MongoDB 不会默认在 admin 库查用户,除非你明说。
- 错误写法:
mongodb://svc:xxx@localhost:27017/myapp→ 驱动会尝试在myapp库里找用户,失败 - 正确写法:
mongodb://svc:xxx@localhost:27017/myapp?authSource=admin - Spring Boot 用户注意:
spring.data.mongodb.uri必须包含?authSource=admin,光配username/password属性无效 - Robo 3T / Compass 中,“Authentication Database”字段必须填
admin,留空或填错库名,连接直接报Unauthorized
真正麻烦的从来不是“怎么加认证”,而是加完之后没人检查客户端是否同步更新了连接参数,也没人验证旧连接是否已被强制断开。一个没清理干净的长连接,可能让整个加固形同虚设。











