【问题标题】:How to use Spring to connect to MongoDB which requires authentication如何使用 Spring 连接需要身份验证的 MongoDB
【发布时间】: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://&lt;user&gt;:&lt;password&gt;@&lt;host&gt;:27017

但是,我遇到了身份验证错误。 我的理解是 MongoUI 可以采用上述格式的 URL。

我知道 mongoTemplate 可以接受 userCredentials 对象,但是我需要先从 URL 中提取它们,我不确定如何在配置中执行此操作。

知道如何更改上面的配置以支持此假设 mongo.url 格式无法更改?

【问题讨论】:

  • 尝试打乱 bean 条目的顺序
  • 呃??? Spring 配置中 bean 的顺序无关紧要,这是基本的 Spring

标签: spring mongodb


【解决方案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 描述中最好使用&lt;constructor-arg ... 而不是&lt;property ...
    • 只针对单个 MongoDB 实例,不针对 Replica Set
    • 你能解释一下#{mongoURI.username}#{new java.lang.String(mongoURI.password)}
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多