OperationFailure: not authorized on tracking to execute command

15,108

Solution 1

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)

Solution 2

Here's a means of connecting and authenticating with pymongo:

from pymongo import MongoClient

# MongoDB connection info
hostname = '10.20.30.40'
port = 27017
username = 'adminUserName'
password = 'secret'
databaseName = 'someDB'

# connect with authentication
client = MongoClient(hostname, port)
db = client[databaseName]
db.authenticate(username, password)
Share:
15,108
Crazyshezy
Author by

Crazyshezy

Data Engineer / Backend Architect

Updated on July 19, 2022

Comments

  • Crazyshezy
    Crazyshezy almost 2 years

    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?

  • Rahul Hindocha
    Rahul Hindocha almost 2 years
    I tried this code but got error that authenticate method does not exist. TypeError: 'Collection' object is not callable. If you meant to call the 'authenticate' method on a 'Database' object it is failing because no such method exists.