Home > Blockchain >  PyMongo: "not authorized on db to execute command" but roles and credentials are ok
PyMongo: "not authorized on db to execute command" but roles and credentials are ok

Time:02-18

I have two users, admin and user.

use admin
db.getUser('admin')
{
  _id: 'admin.admin',
  userId: UUID("xx"),
  user: 'admin',
  db: 'admin',
  roles: [
    { role: 'userAdminAnyDatabase', db: 'admin' },
    { role: 'readWriteAnyDatabase', db: 'admin' }
  ],
  mechanisms: [ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ]
}
use mydb
db.getUser('user')
{
  _id: 'mydb.user',
  userId: UUID("xx"),
  user: 'user',
  db: 'mydb',
  roles: [ { role: 'readWrite', db: 'mydb' } ],
  mechanisms: [ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ]
}

If I log in as user using mongosh or MongoDB Compass I can totally do any read or write queries, but if I try anything using a PyMongo cursor:

r = list(mongo.db.mycollection.find())

I get:

pymongo.errors.OperationFailure: not authorized on db to execute command { find: "mycollection", filter: {}, lsid: { id: UUID("xx") }, $db: "db", $readPreference: { mode: "primaryPreferred" } }, full error: {'ok': 0.0, 'errmsg': 'not authorized on db to execute command { find: "config", filter: {}, lsid: { id: UUID("xx") }, $db: "db", $readPreference: { mode: "primaryPreferred" } }', 'code': 13, 'codeName': 'Unauthorized'}

But if I do the same using admin instead everything is ok.

My guesses are that it authenticates but does not get inside the specified database, it probably reaches some other default database instead and that's why it says it has not authorization (despite I specified it in the URI).

Here is my URI:

mongodb://user:passwd@localhost:27017/mydb?authSource=mydb&readPreference=primary&appname=myapp&ssl=false

Any ideas how to debug my issue?

CodePudding user response:

I guess python runs some additional queries in background.

From MongoDB documentation:

Roles which are created in other database than admin can only include privileges that apply to its database and can only inherit from other roles in its database.

A role created in the admin database can include privileges that apply to any database or to the cluster resource, and can inherit from roles in other databases as well as the admin database.

I would suggest to create the user in admin database and grant roles accordingly:

db.getSiblindDB("admin").createUser( { 
   user: "user",
   pwd: "<password>"
   roles: [ { role: "readWrite", db: "mydb" }] 
})
  • Related