com.mongodb.MongoQueryException: Query failed with error code 13

今天一个现场运维部署群里面发现一些应用日志报错,如图:
error_1.png
那个项目的负责人当时有其余事,就@我帮忙解决一下。我第一反应是没有受权,可是运维人员说已经执行过受权语句了,而且能够在命令行用那个用户名密码登陆,也能够看到集合(他没有find数据只是show collections看了一下集合列表)。我很久没有看MongoDB的东西了,MongoDB的内置角色权限细节已经记不清了,因此看到群里他发出来的受权语句也没有发现角色不对,致使后来走了一些弯路。特此记录下,防止之后再弄错。
如题所示,错误是当前用户没有find读取数据的权限,运维人员的受权语句以下:mongodb

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经过基于角色的受权来授予对数据和命令的访问权限,并提供了一些内置角色来知足平常对数据库的不一样级别的访问。
用户角色有readreadWrite
数据库系统管理员角色有dbAdmindbOwneruserAdmin
等等,更多角色及每一个角色对应的权限详见mongdb内置角色
运维人员弄混的角色就是dbAdmindbOwner,由于咱们测试库中有时候为了方便操做,会给的权限比较高,因此常常给用户授予管理员的角色dbOwner,少数授予了dbAdmin,运维人员给新环境写受权语句的时候参考了测试库的角色,可是没弄清楚这两个角色的区别:app

  • 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角色授予的权限。