今天一个现场运维部署群里面发现一些应用日志报错,如图:
那个项目的负责人当时有其他事,就@我帮忙解决一下。我第一反应是没有授权,但是运维人员说已经执行过授权语句了,并且可以在命令行用那个用户名密码登录,也可以看到集合(他没有find数据只是show collections看了一下集合列表)。我好久没有看MongoDB的东西了,MongoDB的内置角色权限细节已经记不清了,所以看到群里他发出来的授权语句也没有发现角色不对,导致后来走了一些弯路。而且在网上查询资料的话,会看到好几种情况都是这个错误码,需要根据自己的情况仔细排查。所以在这里记录下,防止以后再弄错,同时也给大家提个醒。
如题所示,错误是当前用户没有find读取数据的权限,运维人员的授权语句如下:
use userDb;
db.createUser(
{
user:"userName",
pwd:"userPwd",
roles: [{ role:"dbAdmin", db:"userDb"} ]
}
)
实际上此时使用该用户在命令行登录之后,也是没有权限find非系统集合数据的。由于这个应用只是对一个普通集合的数据进行读写,所以正确的做法是把角色设为readWrite,更新语句为
> use userDb
switched to db userDb
> db.updateUser("userName",{roles:[{"role":"readWrite","db":"userDb"}]})
大家都知道MongoDB通过基于角色的授权来授予对数据和命令的访问权限,并提供了一些内置角色来满足日常对数据库的不同级别的访问。
用户角色有read
、readWrite
数据库系统管理员角色有dbAdmin
、dbOwner
、userAdmin
等等,更多角色及每个角色对应的权限详见mongdb内置角色
运维人员弄混的角色就是dbAdmin
、dbOwner
,因为我们测试库中有时候为了方便操作,会给的权限比较高,所以经常给用户授予管理员的角色dbOwner,少数授予了dbAdmin,运维人员给新环境写授权语句的时候参考了测试库的角色,但是没弄清楚这两个角色的区别:
- dbAdmin 对 system.indexes, system.namespaces, and system.profile集合有以下权限
collStats
dbHash
dbStats
find
killCursors
listIndexes
等等
该角色对非系统集合没有完全读取的访问权限,提供以下操作:
bypassDocumentValidation
collMod
collStats
compact
convertToCapped
createCollection
createIndex
等等
- dbOwner可以对数据库执行任何管理操作,它集合了对readWrite,dbAdmin和userAdmin角色授予的权限。