Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connect to multiple mongo db hosts and authenticate using a different database in spring boot

I have a java application which integrates with mongo db. I happen to have 3 mongo db hosts (all with same port) and they have to be authenticated using a separate db other than the db my application uses. For eg: "admin" is the authentication database name and "contenttest" is the db my application wants to connect to. I have credentials as well (username and password). I tried the following uri to connect, but its not working in spring boot application.

application.properties

spring.data.mongodb.authentication-database=admin
spring.data.mongodb.uri = mongodb://content_rw:<secret password>@a.mongo.db:27017,b.mongo.db:27017,c.mongo.db:27017/contenttest?wtimeoutMS=300&connectTimeoutMS=500&socketTimeoutMS=200

I am getting error saying authentication is unsuccessful with the following error logs.

com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=null, userName='content_rw', source='contenttest', password=<hidden>, mechanismProperties={}}
    at com.mongodb.connection.SaslAuthenticator.wrapInMongoSecurityException(SaslAuthenticator.java:157) ~[mongodb-driver-core-3.4.3.jar!/:na]
    at com.mongodb.connection.SaslAuthenticator.access$200(SaslAuthenticator.java:37) ~[mongodb-driver-core-3.4.3.jar!/:na]
    at com.mongodb.connection.SaslAuthenticator$1.run(SaslAuthenticator.java:66) ~[mongodb-driver-core-3.4.3.jar!/:na]
    at com.mongodb.connection.SaslAuthenticator$1.run(SaslAuthenticator.java:44) ~[mongodb-driver-core-3.4.3.jar!/:na]
    at com.mongodb.connection.SaslAuthenticator.doAsSubject(SaslAuthenticator.java:162) ~[mongodb-driver-core-3.4.3.jar!/:na]
    at com.mongodb.connection.SaslAuthenticator.authenticate(SaslAuthenticator.java:44) ~[mongodb-driver-core-3.4.3.jar!/:na]
    at com.mongodb.connection.DefaultAuthenticator.authenticate(DefaultAuthenticator.java:32) ~[mongodb-driver-core-3.4.3.jar!/:na]
    at com.mongodb.connection.InternalStreamConnectionInitializer.authenticateAll(InternalStreamConnectionInitializer.java:109) ~[mongodb-driver-core-3.4.3.jar!/:na]
    at com.mongodb.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:46) ~[mongodb-driver-core-3.4.3.jar!/:na]
    at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:116) ~[mongodb-driver-core-3.4.3.jar!/:na]
    at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:113) ~[mongodb-driver-core-3.4.3.jar!/:na]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_151]
Caused by: com.mongodb.MongoCommandException: Command failed with error 18: 'Authentication failed.' on server a.mongo.db:27017. The full response is { "ok" : 0.0, "code" : 18, "errmsg" : "Authentication failed." }
    at com.mongodb.connection.CommandHelper.createCommandFailureException(CommandHelper.java:170) ~[mongodb-driver-core-3.4.3.jar!/:na]
    at com.mongodb.connection.CommandHelper.receiveCommandResult(CommandHelper.java:123) ~[mongodb-driver-core-3.4.3.jar!/:na]
    at com.mongodb.connection.CommandHelper.executeCommand(CommandHelper.java:32) ~[mongodb-driver-core-3.4.3.jar!/:na]
    at com.mongodb.connection.SaslAuthenticator.sendSaslStart(SaslAuthenticator.java:117) ~[mongodb-driver-core-3.4.3.jar!/:na]
    at com.mongodb.connection.SaslAuthenticator.access$000(SaslAuthenticator.java:37) ~[mongodb-driver-core-3.4.3.jar!/:na]
    at com.mongodb.connection.SaslAuthenticator$1.run(SaslAuthenticator.java:50) ~[mongodb-driver-core-3.4.3.jar!/:na]
    ... 9 common frames omitted

stacktrace contains similar exceptions for other hosts as well.

I need some help to achieve authentication using a separate db ("admin") and use a different db ("contenttest") when using 3 mongo hosts.

Thanks in advance

like image 676
stallion Avatar asked Oct 25 '17 13:10

stallion


1 Answers

According to the documentation the connection string URI format is:

mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]

The /database part is described as:

Optional. The name of the database to authenticate if the connection string includes authentication credentials in the form of username:password@. If /database is not specified and the connection string includes credentials, the driver will authenticate to the admin database.

You have set up the URI like this:

spring.data.mongodb.uri = mongodb://content_rw:<secret password>@a.mongo.db:27017,b.mongo.db:27017,c.mongo.db:27017/contenttest?wtimeoutMS=300&connectTimeoutMS=500&socketTimeoutMS=200

In your logs we can see the line:

Exception authenticating MongoCredential{mechanism=null, userName='content_rw', source='contenttest', password=<hidden>, mechanismProperties={}}

In MongoCredential.java the source is described as:

the source of the user name, typically the name of the database where the user is defined

So it looks like you have set up the authentication database as /contenttest and not as:

spring.data.mongodb.authentication-database=admin

I think you should remove the database name from the URI and probably spring.data.mongodb.authentication-database property, because admin database is used by default.

Also, look at this:

enter image description here

This line should be interesting in terms of setting up the application database:

spring.data.mongodb.database=test # Database name.
like image 106
cbartosiak Avatar answered Sep 30 '22 10:09

cbartosiak