“not authorized”错误源于权限未覆盖目标数据库或命令类型,需用db.runcommand({connectionstatus: 1})查真实权限,确认authsource匹配用户创建库,并用grantrolestouser安全补权。

“not authorized”错误不是账号没权限,而是权限没覆盖到当前操作的数据库或命令类型——比如你在 myapp 库执行 show collections,但用户只在 admin 库被授予了 readWrite 角色,就会报这个错。
怎么快速确认当前会话真实权限?
别猜,直接运行:db.runCommand({connectionStatus: 1})。它不触发权限检查,只要连得上就能返回结果。
- 必须先
use到你要操作的目标库再执行,否则返回的是默认库(通常是test)的权限视图 - 重点看
authInfo.authenticatedUserRoles数组:如果为空,说明根本没认证成功(authSource写错了) - 如果角色存在,但
db字段不是你正在操作的库名(例如只有{role: "readWrite", db: "admin"}),那对myapp的任何操作都会失败
authSource 写错是最隐蔽的坑
很多工具(Compass、Node.js driver)默认把 authSource 设为 admin,但如果你的用户是在 myapp 库创建的,连接时却指定 ?authSource=admin,MongoDB 就去 admin 库找用户记录——找不到,于是降级为匿名会话。
- 查用户在哪建的:
use myapp→db.runCommand({usersInfo: "myuser"}),看返回里的db字段 - 连接字符串里必须匹配:用户在
myapp库创建,就要写?authSource=myapp - 用
mongosh连接时显式指定:mongosh -u myuser -p --authenticationDatabase myapp
给用户补权限,别删重建
线上环境禁止用 db.updateUser() 覆盖 roles 字段——它会清掉原有所有角色。用 db.grantRolesToUser() 是原子操作,安全叠加。
- 在目标库上下文执行:
use myapp→db.grantRolesToUser("myuser", [{role: "readWrite", db: "myapp"}]) - 跨库操作(如聚合中
$lookup到analytics库)要单独授权:db.grantRolesToUser("myuser", [{role: "read", db: "analytics"}]) - 需要执行
show dbs或listDatabases?MongoDB 6+ 必须显式授予listDatabases@admin角色,readAnyDatabase不再隐含该能力
创建用户时就在目标库执行
不要图省事全在 admin 库建用户。新用户必须在它要操作的库下运行 db.createUser(),否则权限作用域天然不匹配。
- 正确姿势:
use myapp→db.createUser({user: "appuser", pwd: "...", roles: [{role: "readWrite", db: "myapp"}]}) - 管理员账号例外:高权限角色(如
userAdminAnyDatabase、root)必须在admin库创建,且连接时authSource必须是admin - 如果用户已建错位置,补权限比删重建更稳妥,避免应用连接中断
最常被忽略的一点:权限检查发生在「命令执行时」,而不是「连接建立时」。同一个连接切换 use 到不同库后,权限视图会变——所以 db.auth() 后切库,务必重新验证或确保角色已覆盖新库。











