0

In trying to build off of this SO post, I've built the below Python script. It should connect to a remote MongoDB (actually a VM on my local machine), run a simple find() operation, then print the results:

from pymongo import MongoClient
MONGO_HOST = "172.17.0.2"
MONGO_PORT = "27017"
MONGO_DB = "myDB"
MONGO_USER = "me"
MONGO_PASS = "password01"

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

client = MongoClient(uri)    
myDB = client['myDB']
myTable = myDB['TableA']

limited_cursor = myTable.find({ "data1": "KeyStringHere" }, { "_id": 0, "data2" : 1 }).limit(2)
for document in limited_cursor:
    print(document)

When run, the code vomits out a lot of errors:

me@ubuntu1:~/$ /usr/bin/python3 myPythonScript.py
Traceback (most recent call last):
  File "myPythonScript.py", line 14, in <module>
    for document in limited_cursor:
  File "/usr/lib/python3/dist-packages/pymongo/cursor.py", line 1169, in next
    if len(self.__data) or self._refresh():
  File "/usr/lib/python3/dist-packages/pymongo/cursor.py", line 1085, in _refresh
    self.__send_message(q)
  File "/usr/lib/python3/dist-packages/pymongo/cursor.py", line 924, in __send_message
    **kwargs)
  File "/usr/lib/python3/dist-packages/pymongo/mongo_client.py", line 1029, in _send_message_with_response
    exhaust)
  File "/usr/lib/python3/dist-packages/pymongo/mongo_client.py", line 1040, in _reset_on_error
    return func(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/pymongo/server.py", line 85, in send_message_with_response
    with self.get_socket(all_credentials, exhaust) as sock_info:
  File "/usr/lib/python3.6/contextlib.py", line 81, in __enter__
    return next(self.gen)
  File "/usr/lib/python3/dist-packages/pymongo/server.py", line 138, in get_socket
    with self.pool.get_socket(all_credentials, checkout) as sock_info:
  File "/usr/lib/python3.6/contextlib.py", line 81, in __enter__
    return next(self.gen)
  File "/usr/lib/python3/dist-packages/pymongo/pool.py", line 920, in get_socket
    sock_info.check_auth(all_credentials)
  File "/usr/lib/python3/dist-packages/pymongo/pool.py", line 609, in check_auth
    auth.authenticate(credentials, self)
  File "/usr/lib/python3/dist-packages/pymongo/auth.py", line 486, in authenticate
    auth_func(credentials, sock_info)
  File "/usr/lib/python3/dist-packages/pymongo/auth.py", line 466, in _authenticate_default
    return _authenticate_scram_sha1(credentials, sock_info)
  File "/usr/lib/python3/dist-packages/pymongo/auth.py", line 209, in _authenticate_scram_sha1
    res = sock_info.command(source, cmd)
  File "/usr/lib/python3/dist-packages/pymongo/pool.py", line 517, in command
    collation=collation)
  File "/usr/lib/python3/dist-packages/pymongo/network.py", line 125, in command
    parse_write_concern_error=parse_write_concern_error)
  File "/usr/lib/python3/dist-packages/pymongo/helpers.py", line 145, in _check_command_response
    raise OperationFailure(msg % errmsg, code, response)
pymongo.errors.OperationFailure: Authentication failed.
me@ubuntu1:~/$

I'm certain the code is crashing on the last line of the script: for document in limited_cursor: print(document) If I comment out those last two lines, the script runs without error... but generates no output.

However, a careful reading of the traceback errors says the root problem is Authentication failed. So what does that mean? Is my URI incorrect?

I'm pretty sure the URI is correct. When I modify the script to print it to the console:

print(uri)

It comes out:

mongodb://me:password01@172.17.0.2:27017/myDB?authSource=admin

That all looks right to me. The IP address and port are def correct, as is the database name. I've also created a me/password01 user within Mongo. From within the Mongo Shell:

> db.getUsers()
[
        {
                "_id" : "test.me",
                "userId" : UUID("5c3b4f1a-d05f-4015-9f6d-0b6cbbd7026c"),
                "user" : "me",
                "db" : "test",
                "roles" : [
                        {
                                "role" : "userAdminAnyDatabase",
                                "db" : "admin"
                        }
                ],
                "mechanisms" : [
                        "SCRAM-SHA-1",
                        "SCRAM-SHA-256"
                ]
        }
]
>

Any advice or tips is appreciated, thank you.

Pete
  • 1,511
  • 2
  • 26
  • 49

1 Answers1

1

userAdminAnyDatabase role does not allow to search data, it's to manage users.

You need readWriteAnyDatabase role

You created role in the test database but authenticating against admin database: ?authSource=admin. So either change you to ?authSource=test or (recommended) create the user in admin database. In mongo shell:

> use admin;
> db.createUser( { user: "me" ....})
Alex Blex
  • 34,704
  • 7
  • 48
  • 75
  • Hmm. I've changed my user to "readWriteAnyDatabase", but am still getting the same error. When I (re)create the user, I'm using this command: db.createUser( { user: "me", pwd: "password01", roles:[{role: "readWriteAnyDatabase" , db:"admin"}]}) – Pete Jun 24 '22 at 20:35
  • 1
    ah, sorry, did notice you created the user in the `test` database. you are trying to authenticate on `admin` database - the `authSource=admin` thing. So either create a user there or change authSource in the url. And really, consider the course I mentioned the other day. It's free. It explains all of it much better than I do and in a more organised manner. – Alex Blex Jun 24 '22 at 21:27
  • Yes, will do! And thank you for the recommendation on the course. I am taking the course you recommended, this post is actually me trying to apply the lessons of Chapters 1 and 2. They don't discuss authentication issues in the course materials, alas... – Pete Jun 24 '22 at 21:43
  • 1
    I'd recommend to repeat this question on their discussion board. First of all it's curated and you may have an answer from the staff, and secondly they use it as a form of feedback to identify blind spots in the courses and improve them over time. – Alex Blex Jun 24 '22 at 22:06
  • Ah, good idea. Will do. Thanks, Alex! – Pete Jun 25 '22 at 17:00