8

I have following code to save to a local running mongo instance:

MongoCredential credential = MongoCredential.createCredential("myuser", "mydatabase", "mypassword".toCharArray());

MongoClient mongo = MongoClients.create(MongoClientSettings.builder()
                    .applyToClusterSettings(builder -> builder.hosts(Arrays.asList(new 
ServerAddress("localhost", 27017))))
                    .credential(credential)
                    .build());
MongoDatabase database = mongo.getDatabase("mydatabase");
MongoCollection<Document> collection = database.getCollection("mycollection");
collection.insertOne(document);

I have created a user for usernmae/password used in code above using db.createUser() command in mongo.exe shell and these are same credentials I provided while installing mongodb.

db.createUser(
{   user: "myuser",
    pwd: "mypassword",

    roles:[{role: "userAdminAnyDatabase" , db:"admin"}]})

But code fails with:

Exception in thread "main" com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='myuser', source='mydatabase', password=<hidden>, mechanismProperties={}}

What am I missing here?

1
  • Did you enable authentication when you start the service, resp. set it in configuration file? Commented Sep 5, 2020 at 15:32

1 Answer 1

16

Where, i.e. in which database did you create the user? Typically users are created in database admin. When you connect to a MongoDB then you should always specify the authentication database and the database you like to use.

The defaults are a bit confusing and not really consistent, esp. different drivers/tools seem to behave different. See this table to get an overview:

+-------------------------------------------------------------------------------------+
|Connection parameters                                    | Authentication | Current  |
|                                                         | database       | database |
+-------------------------------------------------------------------------------------+
|mongo -u user -p pwd --authenticationDatabase admin myDB |     admin      |   myDB   |
|mongo -u user -p pwd myDB                                |     myDB       |   myDB   |
|mongo -u user -p pwd --authenticationDatabase admin      |     admin      |   test   |
|mongo -u user -p pwd --host localhost:27017              |     admin      |   test   |
|mongo -u user -p pwd                                     |     admin      |   test   |
|mongo -u user -p pwd localhost:27017                     |     test       |   test   | 
|mongosh -u user -p pwd localhost:27017                   |     admin      |   test   | -> Different on mongosh and legacy mongo shell
+-------------------------------------------------------------------------------------+

If you like to use Connection string in URI format, it would correspond to these ones. There it is more consistent and well documented.

+-------------------------------------------------------------------------------------+
|Connection string                                        | Authentication | Current  |
|                                                         | database       | database |
+-------------------------------------------------------------------------------------+
|"mongodb://user:pwd@hostname/myDB?authSource=admin"      |     admin      |   myDB   |
|"mongodb://user:pwd@hostname/myDB"                       |     myDB       |   myDB   |
|"mongodb://user:pwd@hostname?authSource=admin"           |     admin      |   test   |
|"mongodb://user:pwd@hostname"                            |     admin      |   test   |
+-------------------------------------------------------------------------------------+

I guess you created the user in admin database but as you don't specify authenticationDatabase while connecting, Mongo defaults it to mydatabase where it fails, because user does not exist in database mydatabase.

In case you use x.509 Certificates for client authentication, i.e. --authenticationMechanism MONGODB-X509 or authMechanism=MONGODB-X509 then the authentication database always defaults to $external which is more convenient.

Sign up to request clarification or add additional context in comments.

9 Comments

OK, so I think in MongoCredential credential = MongoCredential.createCredential("myuser", "mydatabase", "mypassword".toCharArray());..second argument must be the admin database as I used it for creating user.
Yes, should work. However, then you have to switch the database after connection is established. Typically you don't create any application collection in admin database.
I havent created any collection in admin. But I did this change and it still throws authentication issue.
So now my code is as:MongoCredential credential = MongoCredential.createCredential("myuser", "admin", "mypassword".toCharArray()); But this too throws authentication error.
No, the user-id is test.myuser, i.e. it is defined in test database. Run use admin before you create the user or run db.getSiblingDB('admin').createUser(...) You granted userAdminAnyDatabase on admin database, i.e. you permit the user to create users in admin database. However the user itself it created in test, thus you get authentication error when you try to authenticate in DB admin
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.