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 theadmin
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" }]
})