'pymongo auth failed in python script

I have installed mongodb and enabled auth. and its working find. I can connect it from remote notebook using robomongo application:

Host: SERVER_IP
PORT: 27017
DATEBASE: prod-db
USERNAME: user_name
PASS: user_password
Auth Mechanism: MONGODB-CR

and We can connect from server shell locally using:

$ mongo prod-db -u user_name -p user_password

Everything works fine, but when we try it using pymongo api. authentications failed. below is the python code:

from pymongo import MongoClient

client = MongoClient()
client.prod_db.authenticate('user_name', 'user_password', mechanism='MONGODB-CR')
db = client.prod_db
result = db.users.find()

for document in result:
    print(document)

Tools used:

python 2.7
pymongo versiob 3.3.1
MongoDB shell version: 2.6.10
$ mongod --version
db version v2.6.10
2016-10-31T16:34:59.868+0000 git version: nogitversion
2016-10-31T16:34:59.868+0000 OpenSSL version: OpenSSL 1.0.2g  1 Mar 2016

Error trace:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/pymongo/database.py", line 1018, in authenticate
    connect=True)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/mongo_client.py", line 444, in _cache_credentials
    sock_info.authenticate(credentials)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/pool.py", line 343, in authenticate
    auth.authenticate(credentials, self)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/auth.py", line 464, in authenticate
    auth_func(credentials, sock_info)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/auth.py", line 439, in _authenticate_mongo_cr
    sock_info.command(source, query)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/pool.py", line 239, in command
    read_concern)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/network.py", line 102, in command
    helpers._check_command_response(response_doc, None, allowable_errors)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/helpers.py", line 205, in _check_command_response
    raise OperationFailure(msg % errmsg, code, response)

Solution: problem was with database name, following code works fine:

from pymongo import MongoClient

client = MongoClient('mongodb://user_name:user_password@localhost:27017/prod-db')
db = client['prod-db']

result = db.users.find()
for document in result:
    print document


Solution 1:[1]

If you've tried the above answers (from milos.ai) and you're still getting an error:

pymongo.errors.OperationFailure: Authentication failed.

There's a good chance you need to add ?authSource=admin to the end of your uri.

Here's a working solution that I'm using with MongoDB server version 4.2.6 and MongoDB shell version v3.6.9.

from pymongo import MongoClient

# Replace these with your server details
MONGO_HOST = "XX.XXX.XXX.XXX" 
MONGO_PORT = "27017"
MONGO_DB = "database"
MONGO_USER = "admin"
MONGO_PASS = "pass"

uri = "mongodb://{}:{}@{}:{}/{}?authSource=admin".format(MONGO_USER, MONGO_PASS, MONGO_HOST, MONGO_PORT, MONGO_DB)
client = MongoClient(uri)

And if you're using command line, you'll get the same fix by adding the argument --authenticationDatabase admin

Solution 2:[2]

For pymongo,

Try below for MongoDB 4:

Add authSource : This is the name of the database that has the collection with the user credentials.

Ex:

client = MongoClient(host=<<hostname>>,
                     port=<<port>>, 
                     username=<<user_name>>, 
                     password=<<password>>,
                    authSource="admin")
db_obj = client[db_name]

Edit 1: I have tried this on Mongo 3.x version as well. Working for that too.

Solution 3:[3]

This worked for me ....

import pymongo

client = pymongo.MongoClient("mongodb://username:12%40password@ip:27017/sample_db",authSource="admin") 
db = client['sample_db']

Remember if you have special characters in your password (e.g. #,@) you will need to encode them (see %40) in the password. If you do not do authSource="admin" you will receive authentication errors. username - your mongodb username, ip - ip address as this assumes database is hosted on a remote server. sample_db is the database that you would like to access.

Solution 4:[4]

I solved my similar problem like below;

As pymongo documentation state, you should use urllib for username and pass. https://pymongo.readthedocs.io/en/stable/examples/authentication.html

my code is here;

import os, urllib

user = urllib.parse.quote_plus(os.environ.get('MONGO_USER'))
password = urllib.parse.quote_plus(os.environ.get('MONGO_PASS'))

uri = "mongodb://{}:{}@{}:{}".format(user, password, os.environ.get('MONGO_HOST'), os.environ.get('MONGO_PORT'))
## if you have an admin user you should not specify any database name in uri. After connection established you can call get_database('your_db_name')
client = MongoClient(uri)

Note: Authentication requires a username, a password, and a database name. The default database name is “admin”, this can be overridden with the authSource option. So you do not have to specify authSource if you have a root user which can be accessed any database. Default is already .

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 user8291021
Solution 4 Tuncay Elvanağaç