MongoDB默认安装后并不要求身份验证,任何能连接27017端口的客户端都能执行任意数据库操作。这种做法适合本地开发,但一旦暴露在公网或内网中,数据几乎等于裸奔。admin数据库并不是用来存放业务数据的,它内部保存着系统集合、用户信息、角色定义等元数据。当我们在admin库下创建用户并赋予相应角色后,这个用户就具备了实例级或库级的管理权限。因此,MongoDB授权登录admin实际上包含两个动作:设置认证开关和创建管理员账号,二者的顺序直接决定登录能否成功。

理解认证与admin库的角色体系
MongoDB的认证和授权是两个独立的过程。认证解决“你是谁”,授权解决“你能做什么”。当客户端连接数据库时,必须先通过认证,然后根据用户绑定的角色决定可以执行哪些操作。admin数据库在这一体系中处于最高层级,它承载了实例级角色(如clusterAdmin、root、userAdminAnyDatabase等),这些角色可以管理其他所有数据库和集群配置。
很多刚接触MongoDB的人会把admin库当成一个普通的业务库来用,其实并不合适。admin库中的用户信息存储在system.users集合里,而角色定义则保存在system.roles集合。只有被赋予admin库相关角色的用户,才有权限操作这些系统集合。例如,userAdmin角色只能管理当前库的用户和角色,而userAdminAnyDatabase角色则可以跨库管理所有用户。理解这一点,才能避免后续授权时出现权限不足的困惑。
此外,MongoDB还区分了认证库(authentication database)和角色库(database in role definition)。一个用户可以在admin库中创建,但它的角色可以指向其他业务库。登录时必须指定认证库为admin,否则服务端会去错误的库中查找用户凭证,导致认证失败。这是实际使用中最容易踩的坑。
创建管理员账号并开启认证模式
要让MongoDB强制登录认证,必须先有一个具有管理权限的用户。创建流程分为两步:先在未开启认证的状态下启动mongod,进入shell创建管理员账号;然后重启mongod并加上--auth参数。如果顺序反了,先开启认证再想创建用户,就会因为没有可用账号而无法登录,陷入死锁。
下面是创建管理员用户的完整过程。启动mongod时不要带--auth,默认配置即可。打开终端,执行mongo进入shell,切换到admin数据库,然后使用db.createUser方法创建用户。这里以创建一个拥有root角色的超级管理员为例:
use admin
db.createUser({
user: "admin",
pwd: "yourStrongPassword",
roles: [
{ role: "root", db: "admin" }
]
})
root角色拥有实例的所有权限,包括对所有数据库的读写、用户管理、配置修改等。生产环境中更推荐使用userAdminAnyDatabase加上readWriteAnyDatabase的组合,而不是直接给root,这样符合最小权限原则。创建成功后,系统会返回Successfully added user提示。接着关闭mongod进程,重新启动并加上--auth参数:
mongod --dbpath /data/db --auth
此时MongoDB已经开启了认证,任何未提供有效凭证的连接都会被拒绝。需要注意的是,如果之前有其他业务库已经在运行,开启认证后也需要为这些库分别创建对应的用户并授予读写权限,否则应用会全部连不上。
登录admin数据库的几种方式
开启认证模式后,可以通过mongo shell命令行登录。最直接的方式是使用-u、-p和--authenticationDatabase参数。认证库必须指定为admin,因为用户是在admin库中创建的。例如:
mongo --host localhost --port 27017 -u admin -p yourStrongPassword --authenticationDatabase admin
如果不想在命令行暴露密码,可以只输入-u参数,执行后会提示输入密码。登录成功后,shell会出现提示符,可以通过db.runCommand({ connectionStatus: 1 })查看当前认证信息,确认用户和角色正确。
对于使用驱动连接的应用,通常采用URI连接串的形式。连接串中同样要标明认证数据库。例如在Node.js或Java驱动中,可以这样写:
mongodb://admin:yourStrongPassword@localhost:27017/admin
连接串末尾的/admin就表示认证数据库是admin。如果省略这一部分,驱动默认会使用当前连接的数据库作为认证库,而用户并不存在于那个库中,就会报Authentication failed错误。因此,凡是登录admin用户,连接串末尾一定要带上/admin。
常见登录失败排查与安全加固
实际运维中,授权登录admin最常见的报错是Authentication failed。排查顺序通常从三个方面入手:第一,确认mongod是否真的开启了--auth参数,如果没有开启,用户和密码输入与否都不影响连接,但不会有认证错误,所以先确认服务端启动参数;第二,检查登录时是否指定了--authenticationDatabase admin,或者连接串末尾是否带了/admin;第三,检查该用户是否是在admin库中创建的,如果用户是在其他库创建的,即使角色为root,认证库也不能写admin。
还有一个容易忽略的问题:角色权限不足。例如用户只有readWrite角色,尝试执行db.createUser操作会被拒绝。此时应当使用具有userAdmin或userAdminAnyDatabase角色的账号来完成用户管理操作。创建新用户时,也应遵循最小权限原则,避免随意授予root角色。对于生产环境,建议为应用单独创建只读或读写账号,为管理员单独创建管理账号,并定期更换密码。
安全加固方面,除了开启认证,还应当限制mongod绑定的IP地址,不要使用0.0.0.0绑定所有网卡。如果服务部署在公网,务必启用TLS加密传输,防止凭证在网络上明文传输。另外,MongoDB 4.0之后支持SCRAM-SHA-256认证机制,比旧的MONGODB-CR更安全,创建用户时默认为SCRAM-SHA-256,无需额外配置,但要注意客户端驱动版本是否支持。通过以上配置,可以最大程度降低未授权访问的风险。