OperationFailure: not authorized on tracking to execute command

Crazyshezy picture Crazyshezy · Mar 14, 2016 · Viewed 12.2k times · Source

I did the following

-- `sudo apt-get install mongodb-org`
-- go to `etc/mongod.conf` change bindIp to: `0.0.0.0`
-- sudo mkdir /data/db
-- start without auth to create user
    `sudo mongod --port 27017 --dbpath /data/db`
-- open shell with : mongo --port 27017

```
> use admin
> db.createUser( { user: "useradmin", pwd: "mypassword", roles: [ { role: "root", db: "admin" } ] } )

```

-- Restart with auth required(ctrl+c the above mongod process): 
`sudo mongod --auth --port 27017 --dbpath /data/db'

-- To open shell(ctrl+c above mongo shell): 
`mongo --port 27017 -u useradmin -p mypassword --authenticationDatabase admin`

my mongoengine_settings.py

```PYTHON
from mongoengine import connect

DATABASE = 'tracking'
USERNAME = 'useradmin'
PASSWORD = 'mypassword'
HOST = 'mongodb://localhost/tracking'
PORT = 27017

connect(DATABASE, 
        username=USERNAME, 
        password=PASSWORD,
        host=HOST,
        port=PORT
        )

```

now when i try to bulk insert some data using mongoengine that works fine if i don't have --auth enabled, otherwise it throws the following error:

OperationFailure(u'command SON([(\'createIndexes\', u\'order\'), (\'indexes\', [{\'unique\': True, \'background\': False, \'sparse\': False, \'key\': SON([(\'order_id\', 1)]), \'name\': u\'order_id_1\'}])]) on namespace tracking.$cmd failed: not authorized on tracking to execute command { createIndexes: "order", indexes: [ { unique: true, background: false, sparse: false, key: { order_id: 1 }, name: "order_id_1" } ] }',)

what am i doing wrong?

Answer

William Byrne III picture William Byrne III · Mar 22, 2016

MongoDB users are created in a specific database rather than at the instance level. Once created users can be granted different roles for different databases. The database a user is created in is called their authentication database

Because usernames are not unique (only the combination of username and authentication database is) you can create two users with the same name in different databases with different roles and passwords. This also means that when connecting you need to specify the authentication database as well as the username and password.

This is why after creating the useradmin user in the admin database you needed to run this command:

mongo --port 27017 -u useradmin -p mypassword --authenticationDatabase admin

to connect the MongoDB shell to the default database test.

If you don't specify the authentication database explicitly then MongoDB assumes the database you are connecting to is also the authentication database. So connecting to the admin database like this would have worked:

mongo --port 27017 -u useradmin -p mypassword admin

and these three commands are effectively the same and all will return an "Authentication failed" error :

mongo --port 27017 -u useradmin -p mypassword mongo --port 27017 -u useradmin -p my password test mongo --port 27017 -u useradmin -p my password test --authenticationDatabase test


To connect from Python, if you use MongoClient and pass it a complete MongoDB URI, the connection string can include optional parameters. One of the options is authSource (the the database name associated with the user’s credentials) which is obviously what you need: connection options.

Your URI will look something like this:

MdbURI = "mongodb://useradmin:mypassword@localhost:27017/tracking?authSource=admin" client = MongoClient(MdbURI)