Authentication error when accessing mongodb throug

2020-06-08 13:54发布

问题:

I have some trouble connecting to a remote mongodb from a java spring boot application. The MongoDB server has no firewall set up, and I can connect to mongo remotely from another machine. I have a database with collections and a user set up. When I try to connect to the database from my java app with the user credentials, I get an exception:

com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=null, userName='sokrates', source='homeControl', password=<hidden>, mechanismProperties={}}
at com.mongodb.connection.SaslAuthenticator.authenticate(SaslAuthenticator.java:61) ~[mongodb-driver-core-3.2.2.jar:na]
at com.mongodb.connection.DefaultAuthenticator.authenticate(DefaultAuthenticator.java:32) ~[mongodb-driver-core-3.2.2.jar:na]
at com.mongodb.connection.InternalStreamConnectionInitializer.authenticateAll(InternalStreamConnectionInitializer.java:99) ~[mongodb-driver-core-3.2.2.jar:na]
at com.mongodb.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:44) ~[mongodb-driver-core-3.2.2.jar:na]
at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:115) ~[mongodb-driver-core-3.2.2.jar:na]
at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:128) ~[mongodb-driver-core-3.2.2.jar:na]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_92]
Caused by: com.mongodb.MongoCommandException: Command failed with error 18: 'Authentication failed.' on server localhost: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.2.2.jar:na]
at com.mongodb.connection.CommandHelper.receiveCommandResult(CommandHelper.java:123) ~[mongodb-driver-core-3.2.2.jar:na]
at com.mongodb.connection.CommandHelper.executeCommand(CommandHelper.java:32) ~[mongodb-driver-core-3.2.2.jar:na]
at com.mongodb.connection.SaslAuthenticator.sendSaslStart(SaslAuthenticator.java:95) ~[mongodb-driver-core-3.2.2.jar:na]
at com.mongodb.connection.SaslAuthenticator.authenticate(SaslAuthenticator.java:45) ~[mongodb-driver-core-3.2.2.jar:na]
... 6 common frames omitted

When I use the same code to connect to a local MongoDB, with the same setup, database, collections and user, all is OK.

I had a little trouble with setting an admin user up on the mongo installation. Also, the local mongo runs on OSX, whereas the production mongo (that fails to authenticate) runs on Ubuntu Server 16.04. I have researched other MongoDB authentication threads for two days now, but none could solve this issue for me. Any help with this is appreciated :-)

Thanks,

Stefan

回答1:

I found the problem. For completeness of this thread, I'll share the answer, including the code. The issue was that I used the application property spring.data.mongodb.uri wrong: it did not have the username and password in the URI, because I mistakenly believed that spring.data.mongodb.username and spring.data.mongodb.password covered that. So, either use the uri with username and password, or use the host and database (and maybe also port) spring properties explicitly. Here is the code. It will work in the spring boot app with mongoDB support (use initializr or IntelliJ to create that project). I have a model:

package net.IndyStef.model;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "person")
public class Person {

@Id
private String id;

private String name;
private Integer age;

public Person() {
}

public Person(String id) {
    this.id = id;
}

public Person(String id, String name, Integer age) {
    this.id = id;
    this.name = name;
    this.age = age;
}

... getters/setters omitted for breverity ...
}

The data is read and written through a repository:

package net.IndyStef.repository;

import net.okrongli.model.Person;
import org.springframework.data.mongodb.repository.MongoRepository;

/**
 * Created by IndyStef on 23/08/16.
 */
public interface PersonRepository extends MongoRepository<Person, String> {
}

The database name, host, and credentials are in the application.properties file:

spring.data.mongodb.host=192.168.1.90
spring.data.mongodb.database=people
spring.data.mongodb.username=user
spring.data.mongodb.password=password
#spring.data.mongodb.uri=mongodb://192.168.1.90/people

Important is to not mix the uri with database and username. If you use uri, it needs to include the username and password, like this:

spring.data.mongodb.uri=mongodb://user:password@192.168.1.90/people

To test this, I used a simple Spring command line runner:

package net.IndyStef;

import net.IndyStef.model.Person;
import net.IndyStef.repository.PersonRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.util.List;

@SpringBootApplication
public class MongoDbTestApplication implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(MongoDbTestApplication.class, args);
    }

    @Autowired
    private PersonRepository repository;

    @Override
    public void run(String... args) {

        repository.save(new Person("peter.pan", "Peter Pan", 865));

        List<Person> people = repository.findAll();

        for (Person person: people) {
            System.out.println(person);
        }
    }
}

I hope this explanation helps others that couldn't figure it out, like myself for a couple of days.

Thanks,

Stefan



回答2:

As of Spring Boot 1.5.15, you can add the following line to your application.properties file:

spring.data.mongodb.uri=mongodb://username:password@localhost:27017/?authSource=admin&authMechanism=SCRAM-SHA-1
spring.data.mongodb.database=mycollection


回答3:

This is what worked for me at then end:

spring.data.mongodb.uri=mongodb://user:password@******.mongodb.net:27017/dbname?ssl=true&authSource=admin&authMechanism=SCRAM-SHA-1

I had to add ssl=true, otherwise I was getting error:

com.mongodb.MongoSocketReadException: Prematurely reached end of stream