如何使用Spring连接需要身份验证的MongoDB

14

我正在使用以下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中,<user>代表用户名,<password>代表密码,<host>代表主机名。

但我遇到了一个身份验证错误。 据我所知,MongoUI可以使用上述格式的URL。

我知道mongoTemplate可以接受userCredentials对象,但是我需要先从URL中提取它们,而我不知道如何在配置中实现这一点。

有什么想法可以改变我的配置以支持此功能,假设不能更改mongo.url格式?


尝试随机排列bean条目的顺序。 - Ravi Khakhkhar
Spring 配置文件中 bean 的顺序不重要,这是 Spring 的基本特性。 - Joly
3个回答

22

使用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>

4
在"mongoCredentials" bean的描述中,最好使用<constructor-arg ...>代替<property ...> - Vlad Minaev
这是针对单个 MongoDB 实例的,不适用于副本集。 - Mr Lou
你能解释一下 #{mongoURI.username}#{new java.lang.String(mongoURI.password)} 吗? - Half Blood Prince

14

如果您想使用Java配置添加身份验证

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

}

2
现在更容易覆盖getUserCredentials()方法并删除mongoTemplate和mongoDbFactory方法。 - cristobal
1
两个问题:1)此代码使用的API现已过时。2)由于在mongoDbFactory()中的“mongo()”调用,可能会导致创建多个不同的MongoClient对象,应该检查是否已经创建了对象并且不要再创建另一个。 - user2080225

8
为了更新@Lealem Admassu的java配置答案,Mongo 3改变了API,现在推荐使用mongo的而不是。
这里有一个简单的例子,展示如何获取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
            )
    );
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接