Java 通过 Spring Boot 应用程序访问 mongodb 时出现身份验证错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39086471/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 20:52:26  来源:igfitidea点击:

Authentication error when accessing mongodb through Spring Boot app

javaspringmongodbspring-boot

提问by IndyStef

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:

我在从 java spring boot 应用程序连接到远程 mongodb 时遇到了一些麻烦。MongoDB 服务器没有设置防火墙,我可以从另一台机器远程连接到 mongo。我有一个包含集合和用户设置的数据库。当我尝试使用用户凭据从我的 java 应用程序连接到数据库时,出现异常:

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.

当我使用相同的代码连接到本地 MongoDB 时,使用相同的设置、数据库、集合和用户,一切正常。

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 :-)

我在 mongo 安装中设置管理员用户时遇到了一些麻烦。此外,本地 mongo 在 OSX 上运行,而生产 mongo(无法通过身份验证)在 Ubuntu Server 16.04 上运行。我已经研究了其他 MongoDB 身份验证线程两天了,但没有一个可以为我解决这个问题。对此的任何帮助表示赞赏:-)

Thanks,

谢谢,

Stefan

斯特凡

采纳答案by IndyStef

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:

我发现了问题。为了这个线程的完整性,我将分享答案,包括代码。问题是我错误地使用了应用程序属性 spring.data.mongodb.uri:它在 URI 中没有用户名和密码,因为我错误地认为 spring.data.mongodb.username 和 spring.data.mongodb.password涵盖了那个。因此,要么使用带有用户名和密码的 uri,要么显式使用主机和数据库(可能还有端口)spring 属性。这是代码。它将在具有 mongoDB 支持的 Spring Boot 应用程序中工作(使用 initializr 或 IntelliJ 创建该项目)。我有一个模型:

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:

数据库名称、主机和凭据位于 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

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:

重要的是不要将 uri 与数据库和用户名混合。如果使用 uri,则需要包含用户名和密码,如下所示:

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

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

为了测试这一点,我使用了一个简单的 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);
        }
    }
}

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

我希望这个解释可以帮助其他人无法弄清楚,比如我自己几天。

Thanks,

谢谢,

Stefan

斯特凡

回答by Sam

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

从 Spring Boot 1.5.15 开始,您可以将以下行添加到您的application.properties文件中:

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

回答by Sharan Toor

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:

我必须添加ssl=true,否则我会收到错误:

com.mongodb.MongoSocketReadException: Prematurely reached end of stream

com.mongodb.MongoSocketReadException:过早到达流末尾