使用ssl从spring boot app连接到MongoDB

时间:2017-02-20 22:33:28

标签: mongodb ssl spring-boot

我尝试使用ssl将我的spring启动应用程序连接到mongodb。我按照这里描述的步骤,但他们不适合我。

https://www.compose.com/articles/how-to-connecting-to-compose-mongodb-with-java-and-ssl/

任何想法?

感谢Alem

2 个答案:

答案 0 :(得分:3)

我建议您查看使用MongoDB访问数据https://spring.io/guides/gs/accessing-data-mongodb/以获取基本用法示例。 spring-boot-starter-data-mongodb将为您提供很长的路要走,您需要做的是配置像这样的MongoClientOptions bean

> <appSettings>
>     <add key="MS_WebHookReceiverSecret_Custom" value="7077693b67c9441a3dbbdbe7ac5b655ffdb323a40fd4ff7535d54c8f10e10582"/>
> </appSettings>

并将mongo客户端选项作为参数传递给MongoClient实例,如下所示

    @Bean
    public  MongoClientOptions mongoClientOptions(){
        System.setProperty ("javax.net.ssl.keyStore","<<PATH TO KEYSTOR >>");
        System.setProperty ("javax.net.ssl.keyStorePassword","PASSWORD");   
        MongoClientOptions.Builder builder = MongoClientOptions.builder();
        MongoClientOptions options=builder.sslEnabled(true).build();        
        return options;
    }

使用

启动mongo进程时进一步添加

mongo --ssl --sslAllowInvalidCertificates --host --port

连接到mongo进程的客户端不必设置任何选项来支持它。

我使用这篇文章Spring data mongodb, how to set SSL?和本spring.io指南作为参考。

希望它有所帮助

答案 1 :(得分:2)

如果您只想将Spring Boot应用程序与mongodb连接,则可以将keyStore和trustStore与Java代码一起使用。因此,您不必通过命令行添加证书。如果使用的是Cloud Foundry,则可以将应用程序与mongodbServices连接,然后在System.getEnv(“ VCAP_SERVICES”)中拥有所需的所有凭据。

@Configuration
public class MongoConfiguration extends AbstractMongoConfiguration {
    private static Log logger = LogFactory.getLog(MongoConfiguration.class);
    @Value("${spring.data.mongodb.database}")
    private String defaultDatabase; //database you want to connect
    private String host;
    private int port;
    private String authenticationDb; //usually admin
    private String username;
    private char[] password;
    private String certificateDecoded; //your CA Certifcate decoded (starts with BEGIN CERTIFICATE)

    public MongoConfiguration() {
        //method for credentials initialization
    }

    //you can't set replicaset=replset in mongooptions so if you want set replicaset, you have to use 
    // customEditorConfigurer in combintaion with class that implementsPropertyEditorRegistrar
    @Bean
    public static CustomEditorConfigurer customEditorConfigurer(){
        CustomEditorConfigurer configurer = new CustomEditorConfigurer();
        configurer.setPropertyEditorRegistrars(
                new PropertyEditorRegistrar[]{new ServerAddressPropertyEditorRegistrar()});
        return configurer;
    }

    @Override
    protected String getDatabaseName() {
        return authenticationDb;
    }

    @Override
    @Bean
    public MongoClient mongoClient() {
        MongoClient mongoClient = new MongoClient(Arrays.asList(new ServerAddress(host, port)), mongoCredentials(), mongoClientOptions());
        return mongoClient;
    }

    @Bean
    public MongoClientOptions mongoClientOptions() {
        MongoClientOptions.Builder mongoClientOptions = MongoClientOptions.builder().sslInvalidHostNameAllowed(true).sslEnabled(true);
        try {
            InputStream inputStream = new ByteArrayInputStream(certificateDecoded.getBytes(StandardCharsets.UTF_8));
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            X509Certificate caCert = (X509Certificate) certificateFactory.generateCertificate(inputStream);

            TrustManagerFactory trustManagerFactory = TrustManagerFactory
                    .getInstance(TrustManagerFactory.getDefaultAlgorithm());
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null); // You don't need the KeyStore instance to come from a file.
            keyStore.setCertificateEntry("caCert", caCert);

            trustManagerFactory.init(keyStore);

            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
            mongoClientOptions.sslContext(sslContext);
            mongoClientOptions.sslInvalidHostNameAllowed(true);
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }

        return mongoClientOptions.build();
    }

    private MongoCredential mongoCredentials() {
        return MongoCredential.createCredential(username, authenticationDb, password);
    }

//With MongoTemplate you have access to db.
    @Bean
    public MongoTemplate mongoTemplate() {
        SimpleMongoDbFactory factory = new SimpleMongoDbFactory(mongoClient(), defaultDatabase);
        return new MongoClient(factory);

    }
}


public final class ServerAddressPropertyEditorRegistrar implements PropertyEditorRegistrar {
    @Override
    public void registerCustomEditors(PropertyEditorRegistry registry) {
        registry.registerCustomEditor(ServerAddress[].class, new ServerAddressPropertyEditor());
    }
}