如何使用 Spring 连接需要身份验证的 MongoDB
Posted
技术标签:
【中文标题】如何使用 Spring 连接需要身份验证的 MongoDB【英文标题】:How to use Spring to connect to MongoDB which requires authentication 【发布时间】:2012-05-02 06:01:09 【问题描述】:我使用下面的 Spring 配置来连接 mongoDB
<bean id="mongoTemplate" class="org.springframework.data.document.mongodb.MongoTemplate">
<constructor-arg name="mongo" ref="mongo"/>
<constructor-arg name="databaseName" value="$mongodb.dbname"/>
</bean>
<bean class="com.mongodb.MongoURI" id="mongoUri">
<constructor-arg value="$mongodb.url" />
</bean>
<bean class="com.mongodb.Mongo" id="mongo">
<constructor-arg ref="mongoUri" />
</bean>
在哪里mongo.url=mongodb://<user>:<password>@<host>:27017
但是,我遇到了身份验证错误。 我的理解是 MongoUI 可以采用上述格式的 URL。
我知道 mongoTemplate 可以接受 userCredentials 对象,但是我需要先从 URL 中提取它们,我不确定如何在配置中执行此操作。
知道如何更改上面的配置以支持此假设 mongo.url 格式无法更改?
【问题讨论】:
尝试打乱 bean 条目的顺序 呃??? Spring 配置中 bean 的顺序无关紧要,这是基本的 Spring 【参考方案1】:为了更新 @Lealem Admassu 对 java config 的回答,他们在 Mongo 3 中更改了 API,现在建议使用 mongo 的 MongoCredentials
而不是 UserCredentials
。
这里有一个如何获取 MongoClient 的简单示例: http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo.mongo-3.authentication
下一个代码可以模块化完成,但或多或少这对我有用(我需要一个 MongoTemplate):
public MongoTemplate getMongoTemplate(String host, int port,
String authenticationDB,
String database,
String user, char[] password)
throws UnknownHostException
return new MongoTemplate(
new SimpleMongoDbFactory(
new MongoClient(
new ServerAddress(host, port),
Collections.singletonList(
MongoCredential.createCredential(
user,
authenticationDB,
password
)
)
),
database
)
);
【讨论】:
【参考方案2】:如果你想使用 java config 添加身份验证
@Configuration
@EnableMongoRepositories("path.to.your.repository")
public class MongoConfig extends AbstractMongoConfiguration
@Value("$mongodb.name")
private String dbName;
@Value("$mongodb.host")
private String host;
@Value("$mongodb.port")
private Integer port;
@Value("$mongodb.username")
private String userName;
@Value("$mongodb.password")
private String password;
@Override
protected String getDatabaseName()
return this.dbName;
@Override
public Mongo mongo() throws Exception
return new MongoClient(this.host, this.port);
@Override
@Bean
public SimpleMongoDbFactory mongoDbFactory() throws Exception
return new SimpleMongoDbFactory(mongo(), getDatabaseName());
@Override
@Bean
public MongoTemplate mongoTemplate() throws Exception
final UserCredentials userCredentials = new UserCredentials(this.userName, this.password);
final MongoTemplate mongoTemplate = new MongoTemplate(mongo(), getDatabaseName(), userCredentials);
mongoTemplate.setWriteConcern(WriteConcern.SAFE);
return mongoTemplate;
【讨论】:
现在更容易覆盖getUserCredentials()
方法。并删除 mongoTemplate 和 mongoDbFactory 方法。
两个问题:1) 此代码使用了现在已弃用的 API。 2) 由于 mongoDbFactory() 中的“mongo()”调用,代码可能会导致创建多个不同的 MongoClient 对象,它应该检查它是否已经创建了对象而不是创建另一个对象。【参考方案3】:
使用 Spring 表达式语言找到了解决方案
<bean id="mongoTemplate" class="org.springframework.data.document.mongodb.MongoTemplate">
<constructor-arg name="mongo" ref="mongo"/>
<constructor-arg name="databaseName" value="$mongodb.dbname"/>
<constructor-arg name="userCredentials" ref="mongoCredentials"/>
</bean>
<bean id="mongoCredentials" class="org.springframework.data.authentication.UserCredentials">
<property name="username" value="#mongoURI.username" />
<property name="password" value="#new java.lang.String(mongoURI.password)" />
</bean>
<bean class="com.mongodb.MongoURI" id="mongoURI">
<constructor-arg value="$mongodb.url" />
</bean>
<bean class="com.mongodb.Mongo" id="mongo">
<constructor-arg ref="mongoURI" />
</bean>
【讨论】:
在“mongoCredentials”bean 描述中最好使用<constructor-arg ...
而不是<property ...
只针对单个 MongoDB 实例,不针对 Replica Set
你能解释一下#mongoURI.username
和#new java.lang.String(mongoURI.password)
以上是关于如何使用 Spring 连接需要身份验证的 MongoDB的主要内容,如果未能解决你的问题,请参考以下文章
如何以编程方式检查某个 URL 是不是需要使用 Spring Security 进行身份验证?