Search code examples
mongodb

Authentication failure while trying to save to mongodb


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?


Solution

  • 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.