Accessing MongoDB with authentication

0

Authentication is the process of verifying the identity of a user. In this article, we will see how to provide secured access to mongoDB database through authentication process.

If you haven’t installed MongoDb, read here for an introduction and the installation steps.

We will be using Maven as our build tool. In order to access MongoDB Java Driver API, include mongodb-driver artifact.

Dependencies

Add mongodb-driver artifact to your pom.xml.

pom.xml:

<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>com.javarticles.spring.jms</groupId>
	<artifactId>springJms</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<dependencies>
		<dependency>
			<groupId>org.mongodb</groupId>
			<artifactId>mongo-java-driver</artifactId>
			<version>3.2.0</version>
		</dependency>
	</dependencies>

</project>

Steps in authenticating access to MongoDB

In order to authenticate a user, we must first add a user to the MongoDB.

  1. Connect to mongo shell
    C:\mongodb\bin>mongo
    2016-01-02T15:02:21.613+0530 I CONTROL  [main]Hotfix KB2731284 or later update
    is not installed, will zero-out data files
    MongoDB shell version: 3.2.0
    connecting to: test
    <
    
  2. Connect to the admin database
    < use admin
    switched to db admin
    
  3. To create a user, you need to use db.createUser() method. You will assign roles to user based on the operations allowed on the resource where a resource can be either a database, collection, set of collections, or the cluster. The permissions are granted in the form of privileges. The first user created in the database should be a user administrator who has the privileges to manage other users. Let’s create a user administrator.
    < db.createUser(
    ... {
    ... user: "adminuser",
    ... pwd: "admin",
    ... roles: [ "root" ]
    ... }
    ... )
    Successfully added user: { "user" : "adminuser", "roles" : [ "root" ] }
    
  4. Authorization is enabled by restarting the database server using the –auth.
  5. First shut down the server
    < db.shutdownServer()
    
  6. Server is now down.
    < db.shutdownServer()
    2016-01-02T19:11:58.296+0530 I NETWORK  [thread1] trying reconnect to 127.0.0.1:
    27017 (127.0.0.1) failed
    2016-01-02T19:11:58.300+0530 I NETWORK  [thread1] reconnect 127.0.0.1:27017 (127
    .0.0.1) ok
    server should be down...
    
  7. Now restart the database using the –-auth option, which forces user authentication:
    C:\mongodb\bin>mongod.exe --dbpath "C:\mongodb\data" --auth
    
  8. Since the database server is started in secure mode, the client needs to authenticate. Let’s start mongo shell without and try to list the existing databases. You can see below, list databases failed.
    C:\mongodb\bin>mongo
    2016-01-02T19:17:44.350+0530 I CONTROL  [main]Hotfix KB2731284 or later update
    is not installed, will zero-out data files
    MongoDB shell version: 3.2.0
    connecting to: test
    > use mydb
    switched to db mydb
    > show dbs;
    2016-01-02T19:18:51.637+0530 E QUERY    [thread1] Error: listDatabases failed:{
            "ok" : 0,
            "errmsg" : "not authorized on admin to execute command { listDatabases:
    1.0 }",
            "code" : 13
    } :
    [email protected]/mongo/shell/utils.js:23:13
    [email protected]/mongo/shell/mongo.js:53:1
    [email protected]/mongo/shell/utils.js:699:19
    [email protected]/mongo/shell/utils.js:593:15
    @(shellhelp2):1:1
    
  9. Let’s start mongo with authentication details. The client needs to authenticate against the ‘authentication database’.
    authenticationDatabase is the database where we have created the user adminuser. In our case it was database admin.

    C:\mongodb\bin>mongo -u adminuser -p admin --authenticationDatabase admin
    2016-01-02T19:29:55.069+0530 I CONTROL  [main]Hotfix KB2731284 or later update
    is not installed, will zero-out data files
    MongoDB shell version: 3.2.0
    connecting to: test
    
  10. Since mongo shell client has logged in with proper authentication details, listing of databases will work now as myadmin has all privileges.
    > show dbs;
    admin                                      0.000GB
    complexIdTest                              0.000GB
    database                                   0.001GB
    issue                                      0.000GB
    local                                      0.000GB
    mongo-index-db1                            0.000GB
    mongoRepositoryTextSearchIntegrationTests  0.000GB
    mydb                                       0.000GB
    repositories                               0.000GB
    script-tests                               0.000GB
    test                                       0.000GB
    validation                                 0.000GB
    
  11. Connect first to the mongod or mongos instance, and then run the authenticate command or the db.auth() method against the authentication database.
    C:\mongodb\bin>mongo
    2016-01-02T20:14:00.487+0530 I CONTROL  [main]Hotfix KB2731284 or later update
    is not installed, will zero-out data files
    MongoDB shell version: 3.2.0
    connecting to: test
    > use admin
    switched to db admin
    > db.auth('adminuser', 'admin')
    1
    > show dbs;
    admin                                      0.000GB
    complexIdTest                              0.000GB
    database                                   0.001GB
    issue                                      0.000GB
    local                                      0.000GB
    mongo-index-db1                            0.000GB
    mongoRepositoryTextSearchIntegrationTests  0.000GB
    mydb                                       0.000GB
    repositories                               0.000GB
    script-tests                               0.000GB
    test                                       0.000GB
    validation                                 0.000GB
    >
    

MongoClient without authentication

If we start the client without authentication and try to execute some command on the database server, the command is going to fail with ‘not authorized….’ error.

MongoDBWithoutAuthenticationExample:

package com.javarticles.mongodb;

import java.net.UnknownHostException;

import com.mongodb.MongoClient;

public class MongoDBWithoutAuthenticationExample {
    public static void main(String[] args) throws UnknownHostException {

        MongoClient mongoClient = new MongoClient();
        try {
            for (String databaseName : mongoClient.listDatabaseNames()) {
                System.out.println("Database: " + databaseName);
            }
        } finally {
            mongoClient.close();
        }
    }
}

Output:

Jan 02, 2016 7:50:05 PM com.mongodb.diagnostics.logging.JULLogger log
INFO: Cluster created with settings {hosts=[127.0.0.1:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
Jan 02, 2016 7:50:05 PM com.mongodb.diagnostics.logging.JULLogger log
INFO: No server chosen by ReadPreferenceServerSelector{readPreference=primary} from cluster description ClusterDescription{type=UNKNOWN, connectionMode=SINGLE, all=[ServerDescription{address=127.0.0.1:27017, type=UNKNOWN, state=CONNECTING}]}. Waiting for 30000 ms before timing out
Jan 02, 2016 7:50:05 PM com.mongodb.diagnostics.logging.JULLogger log
INFO: Opened connection [connectionId{localValue:1, serverValue:9}] to 127.0.0.1:27017
Jan 02, 2016 7:50:05 PM com.mongodb.diagnostics.logging.JULLogger log
INFO: Monitor thread successfully connected to server with description ServerDescription{address=127.0.0.1:27017, type=STANDALONE, state=CONNECTED, ok=true, version=ServerVersion{versionList=[3, 2, 0]}, minWireVersion=0, maxWireVersion=4, electionId=null, maxDocumentSize=16777216, roundTripTimeNanos=500974}
Jan 02, 2016 7:50:05 PM com.mongodb.diagnostics.logging.JULLogger log
INFO: Opened connection [connectionId{localValue:2, serverValue:10}] to 127.0.0.1:27017
Jan 02, 2016 7:50:05 PM com.mongodb.diagnostics.logging.JULLogger log
INFO: Closed connection [connectionId{localValue:2, serverValue:10}] to 127.0.0.1:27017 because the pool has been closed.
Exception in thread "main" com.mongodb.MongoCommandException: Command failed with error 13: 'not authorized on admin to execute command { listDatabases: 1 }' on server 127.0.0.1:27017. The full response is { "ok" : 0.0, "errmsg" : "not authorized on admin to execute command { listDatabases: 1 }", "code" : 13 }
	at com.mongodb.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:86)
	at com.mongodb.connection.CommandProtocol.execute(CommandProtocol.java:119)
	at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:159)
	at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:286)
	at com.mongodb.connection.DefaultServerConnection.command(DefaultServerConnection.java:173)
	at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:215)
	at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:206)
	at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:112)
	at com.mongodb.operation.ListDatabasesOperation$1.call(ListDatabasesOperation.java:104)
	at com.mongodb.operation.ListDatabasesOperation$1.call(ListDatabasesOperation.java:101)
	at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:239)
	at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:212)
	at com.mongodb.operation.ListDatabasesOperation.execute(ListDatabasesOperation.java:101)
	at com.mongodb.operation.ListDatabasesOperation.execute(ListDatabasesOperation.java:53)
	at com.mongodb.Mongo.execute(Mongo.java:773)
	at com.mongodb.Mongo$2.execute(Mongo.java:760)
	at com.mongodb.OperationIterable.iterator(OperationIterable.java:47)
	at com.mongodb.ListDatabasesIterableImpl.iterator(ListDatabasesIterableImpl.java:57)
	at com.mongodb.MappingIterable.iterator(MappingIterable.java:36)
	at com.mongodb.MappingIterable.iterator(MappingIterable.java:24)
	at com.javarticles.mongodb.MongoDBWithoutAuthenticationExample.main(MongoDBWithoutAuthenticationExample.java:12)

MongoClient authentication

Let’s instantiate MongoClient with the authentication details and then try getting the database names.
We pass in security credentials, the user, authentication database and the password.

MongoCredential.createCredential("adminuser", "admin", "admin".toCharArray())

MongoDBWithAuthenticationExample:

package com.javarticles.mongodb;

import java.net.UnknownHostException;
import java.util.Arrays;

import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;

public class MongoDBWithAuthenticationExample {
    public static void main(String[] args) throws UnknownHostException {

        MongoClient mongoClient = new MongoClient(new ServerAddress(), 
                Arrays.asList(MongoCredential.createCredential("adminuser", "admin", "admin".toCharArray())));
        try {
            for (String databaseName : mongoClient.listDatabaseNames()) {
                System.out.println("Database: " + databaseName);
            }
        } finally {
            mongoClient.close();
        }
    }
}

Output:

Jan 02, 2016 8:06:10 PM com.mongodb.diagnostics.logging.JULLogger log
INFO: Cluster created with settings {hosts=[127.0.0.1:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
Jan 02, 2016 8:06:10 PM com.mongodb.diagnostics.logging.JULLogger log
INFO: No server chosen by ReadPreferenceServerSelector{readPreference=primary} from cluster description ClusterDescription{type=UNKNOWN, connectionMode=SINGLE, all=[ServerDescription{address=127.0.0.1:27017, type=UNKNOWN, state=CONNECTING}]}. Waiting for 30000 ms before timing out
Jan 02, 2016 8:06:11 PM com.mongodb.diagnostics.logging.JULLogger log
INFO: Opened connection [connectionId{localValue:1, serverValue:129}] to 127.0.0.1:27017
Jan 02, 2016 8:06:11 PM com.mongodb.diagnostics.logging.JULLogger log
INFO: Monitor thread successfully connected to server with description ServerDescription{address=127.0.0.1:27017, type=STANDALONE, state=CONNECTED, ok=true, version=ServerVersion{versionList=[3, 2, 0]}, minWireVersion=0, maxWireVersion=4, electionId=null, maxDocumentSize=16777216, roundTripTimeNanos=935809}
Jan 02, 2016 8:06:11 PM com.mongodb.diagnostics.logging.JULLogger log
INFO: Opened connection [connectionId{localValue:2, serverValue:130}] to 127.0.0.1:27017
Database: admin
Database: complexIdTest
Database: database
Database: issue
Database: local
Database: mongo-index-db1
Database: mongoRepositoryTextSearchIntegrationTests
Database: mydb
Database: repositories
Database: script-tests
Database: test
Database: validation
Jan 02, 2016 8:06:11 PM com.mongodb.diagnostics.logging.JULLogger log
INFO: Closed connection [connectionId{localValue:2, serverValue:130}] to 127.0.0.1:27017 because the pool has been closed.

Download the source code

This was an example about accessing MongoDB in a secured way.

You can download the source code here: mongoDBAuthenticationExample.zip
Share.

Comments are closed.