46

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
1
  • Looks like the user only access to the database specified. So you have to include the full db path to let mongo know that you are only interested authenticating against that particular database. Commented Mar 8, 2020 at 11:44

6 Answers 6

63

Please try something like this:

client = MongoClient("mongodb://user_name:user_password@SERVER_IP/prod-db")
db = client['prod-db']
Sign up to request clarification or add additional context in comments.

3 Comments

yes, but client.prod-db is not working. client['prod-db'] works fine.
with Mongo 3, we need to pass complete Server URI
41

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

1 Comment

That solved it for me. Thanks a lot! Although I didn't need the port.
18

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.

Comments

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.

Comments

0

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 .

Comments

0

I was using pymongo version = 3.4.0 and python version = 3.6.2. Downgraded pymongo to 3.11 and it worked for me.

1 Comment

Do you mean upgraded? 3.11 is larger than 3.4.0.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.