12

I'm using MongoDB 3.2 in my application. The code below demonstrates database initialization logic:

private void dbInit(String dbName) {

    String mongoClientURI = "mongodb://" + DB_URL + ":" + DB_PORT;
    MongoClientURI connectionString = new MongoClientURI(mongoClientURI);

    // enable SSL connection
    MongoClientOptions.builder().sslEnabled(true).build();

    if (this.mongoClient == null) {
        this.mongoClient = new MongoClient(connectionString);
    }

    // create database if doesn't exist
    this.mongoClient.getDatabase(dbName);
}

This code works fine, now I want to introduce access level separation to database.

The steps to do that:

  1. Define users:
use myAppDB
db.createUser(
   {
      "user": "myAdmin",
      "pwd": "123090d1487dd4ab7",
      roles: [ "readWrite", "dbAdmin" ]
   }
)

use myAppDB
db.createUser(
   {
      "user": "guest",
      "pwd": "guest",
      roles: [ "read" ]
   }
)
  1. Re-create the MongoDB 3.2 service in authentication mode: "C:\Program Files\MongoDB\Server\3.2\bin\mongod.exe" --install --dbpath=C:\data\db --logpath=C:\data\log\log.txt --auth --service. And run it.

  2. Change the mongoClientURI connection string to

String mongoClientURI = "mongodb://" + DB_SRV_USR + ":" + DB_SRV_PWD + "@" + DB_URL + ":" + DB_PORT;

where DB_SRV_USR = myAdmin and DB_SRV_PWD = 123090d1487dd4ab7.

  1. Check the authenticated connection in IDEA's Mongo Explorer with the same credentials, everything is OK.

  2. Execute my application and get exception Authentication failed.

My questions:

  1. How to connect to MongoDB 3.2 in Java with username and password? I saw a couple of examples but they are using deprecated methods.

  2. Should I add my users to myAppDB or to admin table? In some tutorials I saw that users are created in admin table is it a good idea or it worth to create users only in a database they are going to work with?

Mike
  • 14,010
  • 29
  • 101
  • 161
  • Do you have an SSL-enabled `mongod`? – Markus W Mahlberg Feb 14 '16 at 14:44
  • 1
    And make sure that you have `myAppDB` appended to your connection string and/or use the [authSource parameter](https://docs.mongodb.org/manual/reference/connection-string/#uri.authSource). – Markus W Mahlberg Feb 14 '16 at 14:49
  • @MarkusWMahlberg, I enabled SSL in the settings of Mongo Explorer plugin. – Mike Feb 14 '16 at 15:18
  • @MarkusWMahlberg, btw, in some tutorials I saw that users are created in `admin` table is it a good idea or it worth to create users only in a database they are going to work with? – Mike Feb 14 '16 at 15:27
  • 1
    ***My*** rule of thumb: if the user only has roles on one DB, create the user there. If the user has roles in multiple DBs, create the user in the "primary" DB (usually the first one he or she connects to). For everything else, I use "admin". – Markus W Mahlberg Feb 14 '16 at 16:42

2 Answers2

18

Tested with mongodb-3.4.2 and mongo-java-driver-3.4.2.jar

(1) Use MongoCredential

MongoCredential credential = MongoCredential.createCredential("user", "database", "passwd".toCharArray());
MongoClient mongoClient = new MongoClient(new ServerAddress("localhost", 27017), Arrays.asList(credential));
MongoDatabase db = mongoClient.getDatabase( "test" );
MongoCollection collection = db.getCollection("mycol");
FindIterable fi = collection.find();
MongoCursor cursor = fi.iterator();

(2) Use MongoClientURI

MongoClientURI uri = new MongoClientURI("mongodb://user:passwd@localhost:27017/?authSource=test");
MongoClient mongoClient = new MongoClient(uri);

There are some variant forms for using MongoCredential and MongoClientURI for different authentication mechanisms, check here for details

Jonathan L
  • 9,552
  • 4
  • 49
  • 38
1

As MarkusWMahlberg correctly noted, it is necessary to note the database name in the connection string.

For instance:

String mongoClientURI = "mongodb://" + DB_SRV_USR + ":" + DB_SRV_PWD + "@" + DB_URL + ":" + DB_PORT + "/" + dbName;
Community
  • 1
  • 1
Mike
  • 14,010
  • 29
  • 101
  • 161