web-dev-qa-db-fra.com

Erreur d'authentification lors de l'accès à mongodb via l'application Spring Boot

J'ai du mal à me connecter à un mongodb distant à partir d'une application de démarrage à ressort Java. Le serveur MongoDB n'a pas de pare-feu configuré et je peux me connecter à mongo à distance à partir d'une autre machine. J'ai une base de données avec collections et une configuration utilisateur. Lorsque j'essaie de me connecter à la base de données depuis mon Java avec les informations d'identification de l'utilisateur, j'obtiens une 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

Lorsque j'utilise le même code pour me connecter à un MongoDB local, avec la même configuration, base de données, collections et utilisateur, tout est OK.

J'ai eu un peu de mal à configurer un utilisateur administrateur sur l'installation de mongo. En outre, le mongo local s'exécute sur OSX, tandis que le mongo de production (qui ne parvient pas à s'authentifier) ​​s'exécute sur Ubuntu Server 16.04. J'ai recherché d'autres threads d'authentification MongoDB depuis deux jours maintenant, mais aucun n'a pu résoudre ce problème pour moi. Toute aide à cet égard est appréciée :-)

Merci,

Stefan

15
IndyStef

J'ai trouvé le problème. Pour l'exhaustivité de ce fil, je vais partager la réponse, y compris le code. Le problème est que j'ai mal utilisé la propriété d'application spring.data.mongodb.uri: il n'y avait pas le nom d'utilisateur et le mot de passe dans l'URI, car je croyais à tort que spring.data.mongodb.username et spring.data.mongodb.password couvert cela. Donc, soit utilisez l'uri avec le nom d'utilisateur et le mot de passe, soit utilisez explicitement les propriétés de l'hôte et de la base de données (et peut-être aussi du port). Voici le code. Cela fonctionnera dans l'application Spring Boot avec le support mongoDB (utilisez initializr ou IntelliJ pour créer ce projet). J'ai un modèle:

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 ...
}

Les données sont lues et écrites via un référentiel:

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> {
}

Le nom de la base de données, l'hôte et les informations d'identification se trouvent dans le fichier application.properties:

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

L'important est de ne pas mélanger l'URI avec la base de données et le nom d'utilisateur. Si vous utilisez uri, il doit inclure le nom d'utilisateur et le mot de passe, comme ceci:

spring.data.mongodb.uri=mongodb://user:[email protected]/people

Pour tester cela, j'ai utilisé un simple exécuteur de ligne de commande Spring:

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);
        }
    }
}

J'espère que cette explication aide d'autres personnes qui n'ont pas pu le comprendre, comme moi pendant quelques jours.

Merci,

Stefan

21
IndyStef

Depuis Spring Boot 1.5.15, vous pouvez ajouter la ligne suivante à votre application.properties fichier:

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

C'est ce qui a fonctionné pour moi à la fin:

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

Je devais ajouter ssl=true, sinon j'obtenais une erreur:

com.mongodb.MongoSocketReadException: fin de flux atteinte prématurément

5
Sharan Toor