Authentication issue while trying from java

I have added myself as a user by running db.createUser() command:

db.createUser({user:“manish”,pwd:“manish”,roles:[{role:“userAdminAnyDatabase”,db:“admin”}]})

In Java code I have code as:

MongoCredential credential = MongoCredential.createCredential(“manish”, “admin”,
“manish”.toCharArray());

    MongoClient mongoClient = MongoClients.create(MongoClientSettings.builder()
            .applyToClusterSettings(builder -> builder.hosts(Arrays.asList(new ServerAddress("localhost", 27017))))
            .credential(credential)
            .build());

    // Accessing the database
    MongoDatabase database = mongoClient.getDatabase("mydb");
    MongoCollection<Document> collection = database.getCollection("mycollection");
    System.out.println(collection.countDocuments());

But I get error:

MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName=‘manish’, source=‘admin’, password=, mechanismProperties={}}

How to get it working?

Hi @Manish_Ghildiyal & welcome in the MongoDB community :muscle: !

I deployed a localhost cluster in docker to run a little test:

docker run --rm -d -p 27017:27017 -h $(hostname) --name mongo mongo:4.4.0 --replSet=test --auth

Then I logged into it:

docker exec -it mongo mongo

And I initialised the single node replica set and create the user:

> rs.initiate()
{
	"info2" : "no configuration specified. Using a default configuration for the set",
	"me" : "hafx:27017",
	"ok" : 1
}
test:SECONDARY> 
test:PRIMARY>
test:PRIMARY> use admin
switched to db admin
test:PRIMARY> db.createUser({user:"manish",pwd:"manish",roles:["readWriteAnyDatabase"]})
Successfully added user: { "user" : "manish", "roles" : [ "readWriteAnyDatabase" ] }

Note that I userAdminAnyDatabase doesn’t have enough permissions to run a query in the “mydb.mycollection” collection. You need readWriteAnyDatabase if you want to read & write somewhere.

Once this is in place, I can execute this code and it works for me:

import com.mongodb.Block;
import com.mongodb.MongoClientSettings;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.connection.ClusterSettings;
import org.bson.Document;

import static java.util.Collections.singletonList;

public class App {
    public static void main(String[] args) {
        MongoCredential credential = MongoCredential.createCredential("manish", "admin", "manish".toCharArray());
        Block<ClusterSettings.Builder> localhost = builder -> builder.hosts(singletonList(new ServerAddress("localhost", 27017)));
        MongoClientSettings settings = MongoClientSettings.builder()
                                                          .applyToClusterSettings(localhost)
                                                          .credential(credential)
                                                          .build();
        MongoClient client = MongoClients.create(settings);
        MongoCollection<Document> col = client.getDatabase("test").getCollection("col");
        System.out.println(col.countDocuments());
    }
}

It’s the same piece of code you are using. I just refactored the code a little and changed the role of the user I created.

Note that you may have another issue because if I try to execute this piece of code with the same user but with the userAdminAnyDatabase role, I get this error:

Exception in thread "main" com.mongodb.MongoCommandException: Command failed with error 13 (Unauthorized): 'not authorized on test to execute command { aggregate: "col", pipeline: [ { $match: {} }, { $group: { _id: 1, n: { $sum: 1 } } } ], cursor: {}, $db: "test", lsid: { id: UUID("8e7f5ef1-7e58-4148-935e-974d48373764") }, $readPreference: { mode: "primaryPreferred" } }' on server localhost:27017. The full response is {"operationTime": {"$timestamp": {"t": 1599489561, "i": 1}}, "ok": 0.0, "errmsg": "not authorized on test to execute command { aggregate: \"col\", pipeline: [ { $match: {} }, { $group: { _id: 1, n: { $sum: 1 } } } ], cursor: {}, $db: \"test\", lsid: { id: UUID(\"8e7f5ef1-7e58-4148-935e-974d48373764\") }, $readPreference: { mode: \"primaryPreferred\" } }", "code": 13, "codeName": "Unauthorized", "$clusterTime": {"clusterTime": {"$timestamp": {"t": 1599489561, "i": 1}}, "signature": {"hash": {"$binary": {"base64": "0n4gHEb72t+aCiUPm62027bZNj8=", "subType": "00"}}, "keyId": 6869747452048572419}}}

In your case, it looks like it’s something else.

Which version of MongoDB are you running and which version of the MongoDB Java Driver are you using?
To run this example, I used Java 13, MongoDB 4.4.0 and the latest version of the MongoDB Java Driver: 4.1.0.

<dependency>
  <groupId>org.mongodb</groupId>
  <artifactId>mongodb-driver-sync</artifactId>
  <version>4.1.0</version>
</dependency>

Here is my Maven config file just in case: pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>java</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>java</name>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>13</maven.compiler.source>
    <maven.compiler.target>13</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.mongodb</groupId>
      <artifactId>mongodb-driver-sync</artifactId>
      <version>4.1.0</version>
    </dependency>
  </dependencies>
  
</project>

Before trying to do this with Java. Please make sure you can connect from the same computer using the Mongo Shell or Mongosh and run the query you are trying to do in Java.

Cheers,
Maxime.

Most likely, you created the new user in the wrong authentication database. Most likely, you forgot to run

use admin

before createUser().

2 Likes

Sorry, you are right. I forgot this while writing my answer but I did type this in reality. I’m editing my post now. Thanks for spotting this :+1:!

My comment was directed to the original poster but indeed, you missed the use admin. B-)

You get an error if you are not in the “admin” database :slight_smile:.

Oops, right, because of the role readWriteAnyDatabase.

However, some roles will work outside the admin database.

> use notAdminDatabase
switched to db notAdminDatabase
> user = {user:"steevej",pwd:"not-my-usual-password",roles:["dbOwner"]}
{
	"user" : "steevej",
	"pwd" : "not-my-usual-password",
	"roles" : [
		"dbOwner"
	]
}
> db.createUser( user )
Successfully added user: { "user" : "steevej", "roles" : [ "dbOwner" ] }
> db.getUsers( { filter : { user : "steevej" } } )
[
	{
		"_id" : "notAdminDatabase.steevej",
		"user" : "steevej",
		"db" : "notAdminDatabase",
		"roles" : [
			{
				"role" : "dbOwner",
				"db" : "notAdminDatabase"
			}
		],
		"mechanisms" : [
			"SCRAM-SHA-1",
			"SCRAM-SHA-256"
		]
	}
]

Yup, I didn’t ran ‘use admin’ command. And hence it put it in a database called ‘test’, which was not there at first place, and hence is created.

Is your issue solved then @Manish_Ghildiyal? If that’s the case, could you please select the answer that helped you and mark your post as resolved?
Thanks :slight_smile:

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.