Connection to MongoDB with authentication fails
Asked Answered
S

4

5

I am using a MongoDB in Version 3 and I created a database named 'logMonitor' and created a user like:

{
    "_id" : "logMonitor.log",
    "user" : "log",
    "db" : "logMonitor",
    "roles" : [
        {
            "role" : "readWrite",
            "db" : "logMonitor"
        }
    ]
}

when I connect to the database by shell with user "log", it returns success, just like this:

[jboss@chonggouapp mongodb]$ mongo logMonitor -u "log" -p "log"

MongoDB shell version: 3.0.6

connecting to: logMonitor

However connection via Java with the following code fails.

    ServerAddress addr = new ServerAddress("10.46.20.65", 27017);
    
    MongoCredential credential = MongoCredential.createMongoCRCredential(
            "log", "logMonitor", "log".toCharArray());
    
    MongoClientOptions options = MongoClientOptions.builder()
            .serverSelectionTimeout(1000)
            .build();
    MongoClient mongoClient = new MongoClient(addr, Arrays.asList(credential), options);
    
    MongoDatabase db = mongoClient.getDatabase("logMonitor");
    
    long c = db.getCollection("sysLog").count();

The following exception is raised:

Exception in thread "main" com.mongodb.MongoTimeoutException: Timed out after 1000 ms while waiting for a server that matches ReadPreferenceServerSelector{readPreference=primary}. Client view of cluster state is {type=UNKNOWN, servers=[{address=10.46.20.65:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSecurityException: Exception authenticating}, caused by {com.mongodb.MongoCommandException: Command failed with error 18: 'auth failed' on server 10.46.20.65:27017. The full response is { "ok" : 0.0, "errmsg" : "auth failed", "code" : 18 }}}]
    at com.mongodb.connection.BaseCluster.createTimeoutException(BaseCluster.java:370)
    at com.mongodb.connection.BaseCluster.selectServer(BaseCluster.java:101)
    at com.mongodb.binding.ClusterBinding$ClusterBindingConnectionSource.<init>(ClusterBinding.java:75)
    at com.mongodb.binding.ClusterBinding$ClusterBindingConnectionSource.<init>(ClusterBinding.java:71)
    at com.mongodb.binding.ClusterBinding.getReadConnectionSource(ClusterBinding.java:63)
    at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:65)
    at com.mongodb.operation.CountOperation.execute(CountOperation.java:172)
    at com.mongodb.operation.CountOperation.execute(CountOperation.java:43)
    at com.mongodb.Mongo.execute(Mongo.java:738)
    at com.mongodb.Mongo$2.execute(Mongo.java:725)
    at com.mongodb.MongoCollectionImpl.count(MongoCollectionImpl.java:167)
    at com.mongodb.MongoCollectionImpl.count(MongoCollectionImpl.java:147)
    at com.baosight.bsfc4.mn.lg.utils.Test.main(Test.java:34)

Can anyone tell me what is the problem? Is someting wrong with my java code?

Thanks.

Stoneblind answered 22/12, 2015 at 11:4 Comment(1)
Is the machine listening on the specified IP-adress or only on localhost? You should check yor mongDB config file for "bind_address".Chondriosome
D
3

Use createMongoCredential() instead and it should create the correct kind of credentials for you.

Dianndianna answered 22/12, 2015 at 21:0 Comment(1)
Just like what you said, I use MongoCredential.createCredential() and it works.Stoneblind
G
3

Solution:

Need to provide dbAdmin role to this user

db.grantRolesToUser("Username", [{ "role" : "dbAdmin", "db" : "DBName" }])
Gelinas answered 25/7, 2019 at 15:14 Comment(0)
J
1

Check Different kinds of methods: http://api.mongodb.com/java/current/com/mongodb/MongoCredential.html

Try using

createCredential(String userName, String database, char[] password)

Instead of

createMongoCRCredential(String userName, String database, char[] password)

The later one uses Challenge-Response protocol which might not be supported/authorised by your MongoDB.

String user="dfasdfgsdfg";
    String database="odhah";
    char[] password="dfgsdfg960".toCharArray();

    MongoCredential credential = MongoCredential.createCredential(user,
            database,
            password);
    MongoClient mongoClient = new MongoClient(new ServerAddress("125.025.125.2", 27017),
            Arrays.asList(credential));

    MongoDatabase db = mongoClient.getDatabase(database);
    MongoCollection<Document> collection = db.getCollection("names");
    System.out.println("connecting to host....."+mongoClient);
    System.out.println("connecting to database....."+collection);

    List<Document> foundDocument = collection.find(new Document("userId","124")).into(new ArrayList<Document>());
    for (int i=0;i<foundDocument.size();i++) {
        System.out.println(">>>"+foundDocument.get(i));

    }
Jonette answered 29/12, 2016 at 12:59 Comment(0)
O
0

Complete code, taking into account Authentication during connection to MongoDB server instance using Java, is:

    //config is a class populating DB properties and credentials from a properties file

  List<ServerAddress> serverAddresses = new ArrayList<>();
    for (String node: config.getNodes()){
        serverAddresses.add( new ServerAddress(node) );
    }
    List<MongoCredential> credentials = new ArrayList<>();
    credentials.add(
            MongoCredential.createCredential(
                    config.getUser(),
                    config.getDb(),
                    config.getPassword().toCharArray()
            )
    );
    MongoClient mongo = new MongoClient( serverAddresses, credentials );
    db = mongo.getDatabase("hippo_reporting");
    collection = db.getCollection(config.getCollection());
// Now, we can do inserts etc...
Operable answered 28/9, 2016 at 13:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.