Reputation: 201
1 - Created user in mongo shell
> use admin
switched to db admin
> db.createUser( { user:"tiger", pwd:"secret", roles: [ { role:"readWrite", db:"zoo" } ] } )
Successfully added user: {
"user" : "tiger",
"roles" : [
{
"role" : "readWrite",
"db" : "zoo"
}
]
}
2 - Connected to database from Java
List<ServerAddress> seeds = new ArrayList<ServerAddress>();
seeds.add( new ServerAddress( "remoteserver" ));
List<MongoCredential> credentials = new ArrayList<MongoCredential>();
credentials.add(
MongoCredential.createMongoCRCredential(
"tiger",
"admin",
"secret".toCharArray()
)
);
MongoClient mongoClient = new MongoClient( seeds); //, credentials );
MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoClient, "zoo");
3 - Insert a row
mongoTemplate.insert(animal, "animal");
4 - Get this error (this code works when I don't use authentication)
2015-05-13 23:11:36.166 ERROR 67846 --- [nio-8443-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.data.mongodb.UncategorizedMongoDbException: { "serverUsed" : "remoteserver:27017" , "ok" : 0.0 , "errmsg" : "auth failed" , "code" : 18}; nested exception is com.mongodb.CommandFailureException: { "serverUsed" : "remoteserver:27017" , "ok" : 0.0 , "errmsg" : "auth failed" , "code" : 18}] with root cause
com.mongodb.CommandFailureException: { "serverUsed" : "remoteserver:27017" , "ok" : 0.0 , "errmsg" : "auth failed" , "code" : 18}
at com.mongodb.CommandResult.getException(CommandResult.java:76)
at com.mongodb.CommandResult.throwOnError(CommandResult.java:131)
at com.mongodb.DBPort$NativeAuthenticator.authenticate(DBPort.java:652)
at com.mongodb.DBPort.authenticate(DBPort.java:364)
at com.mongodb.DBPort.checkAuth(DBPort.java:375)
at com.mongodb.DBTCPConnector.doOperation(DBTCPConnector.java:206)
at com.mongodb.DBCollectionImpl.writeWithCommandProtocol(DBCollectionImpl.java:424)
at com.mongodb.DBCollectionImpl.insertWithCommandProtocol(DBCollectionImpl.java:389)
at com.mongodb.DBCollectionImpl.insert(DBCollectionImpl.java:188)
at com.mongodb.DBCollectionImpl.insert(DBCollectionImpl.java:167)
at com.mongodb.DBCollection.insert(DBCollection.java:93)
at com.mongodb.DBCollection.insert(DBCollection.java:78)
at com.mongodb.DBCollection.insert(DBCollection.java:120)
at org.springframework.data.mongodb.core.MongoTemplate$8.doInCollection(MongoTemplate.java:904)
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:410)
at org.springframework.data.mongodb.core.MongoTemplate.insertDBObject(MongoTemplate.java:899)
at org.springframework.data.mongodb.core.MongoTemplate.doInsert(MongoTemplate.java:721)
at org.springframework.data.mongodb.core.MongoTemplate.insert(MongoTemplate.java:676)
Upvotes: 5
Views: 5228
Reputation: 580
When using the maven dependency with artefactId "spring-boot-starter-data-mongodb" the MongoCredential.createScramSha1Credential was not available.
So here is what I had to do:
A) Include the maven dependency to mongodb in the pom.xml:
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.4.0</version>
</dependency>
B) Using the solution from user4898172 (MongoCredential.createScramSha1Credential)
public Mongo mongo() throws Exception {
List<MongoCredential> credentials = new ArrayList<>();
credentials.add(MongoCredential.createScramSha1Credential(username, database, password.toCharArray()));
return new MongoClient(new ServerAddress(host, port), credentials);
}
These two changes helped me solve the Exeption:
com.mongodb.CommandFailureException: { "serverUsed" : "remoteserver:27017" , "ok" : 0.0 , "errmsg" : "auth failed" , "code" : 18}
(I'm using MongoDB server version: 3.4.0)
The mongodb github site is also a good reference for implementation details.
Upvotes: 1
Reputation: 201
A little digging and I found that Mongo 3 isn't fond of challenge-response and prefers 'MongoCredential.createScramSha1Credential'
List<ServerAddress> seeds = new ArrayList<ServerAddress>();
seeds.add( new ServerAddress( "remoteServer" ));
List<MongoCredential> credentials = new ArrayList<MongoCredential>();
credentials.add(
MongoCredential.createScramSha1Credential(
"username",
"adminDatabase",
"password".toCharArray()
)
);
MongoClient mongoClient = new MongoClient( seeds, credentials );
MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoClient, "applicationDatabase");
mongoTemplate = new MongoTemplate(mongoDbFactory);
Upvotes: 15