连接到多个 mongo db 主机并在 spring boot 中使用不同的数据库进行身份验证

Posted

技术标签:

【中文标题】连接到多个 mongo db 主机并在 spring boot 中使用不同的数据库进行身份验证【英文标题】:Connect to multiple mongo db hosts and authenticate using a different database in spring boot 【发布时间】:2018-04-06 15:53:06 【问题描述】:

我有一个与 mongo db 集成的 java 应用程序。我碰巧有 3 个 mongo db 主机(都具有相同的端口),它们必须使用我的应用程序使用的数据库以外的单独数据库进行身份验证。例如:“admin”是身份验证数据库名称,“contenttest”是我的应用程序想要连接的数据库。我也有凭据(用户名和密码)。我尝试了以下 uri 进行连接,但它在 spring boot 应用程序中不起作用。

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

我收到错误消息,提示身份验证不成功,并显示以下错误日志。

com.mongodb.MongoSecurityException: Exception authenticating MongoCredentialmechanism=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 也包含其他主机的类似异常。

在使用 3 个 mongo 主机时,我需要一些帮助才能使用单独的 db(“admin”)实现身份验证并使用不同的 db(“contenttest”)。

提前致谢

【问题讨论】:

【参考方案1】:

根据documentation的连接字符串URI格式为:

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

/database 部分描述为:

可选。连接时要验证的数据库的名称 字符串包括形式的身份验证凭据 用户名密码@。如果未指定 /database 并且连接 字符串包括凭据,驱动程序将向管理员进行身份验证 数据库。

你已经像这样设置了 URI:

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

在您的日志中,我们可以看到以下行:

Exception authenticating MongoCredentialmechanism=null, userName='content_rw', source='contenttest', password=<hidden>, mechanismProperties=

MongoCredential.java 中,source 被描述为:

用户名的来源,通常是所在数据库的名称 用户已定义

看来您已将身份验证数据库设置为 /contenttest 而不是:

spring.data.mongodb.authentication-database=admin

我认为您应该从 URI 中删除数据库名称,可能还有 spring.data.mongodb.authentication-database 属性,因为默认使用 admin 数据库。

另外,看看这个:

就设置应用程序数据库而言,这一行应该很有趣:

spring.data.mongodb.database=test # Database name.

【讨论】:

感谢@cbartosiak 它帮助...我认为文档指定身份验证数据库不应与uri 一起用作属性,因为我们必须通过单独的属性在uri 和其他数据库中提供身份验证数据库。 . 不管怎样,再次感谢你:)

以上是关于连接到多个 mongo db 主机并在 spring boot 中使用不同的数据库进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章

无法通过 Spark 连接到 Mongo DB

Heroku 没有连接到 Mongo Atlas DB?

Heroku 没有连接到 Mongo Atlas DB?

无法使用 Grails 3.1.1 连接到 mongo DB

无法使用带有 X509 用户的 mongoose 连接到 Mongo DB

通过 R 连接时无法在 mongo DB 中查看集合