Skip to content

Instantly share code, notes, and snippets.

@EliasRanz
Last active June 12, 2024 19:48
Show Gist options
  • Save EliasRanz/758a1a884cf2eb3fea69309f9531c524 to your computer and use it in GitHub Desktop.
Save EliasRanz/758a1a884cf2eb3fea69309f9531c524 to your computer and use it in GitHub Desktop.
Mongo Configuration for Amazon DocumentDB utilizing Spring-Boot and spring-data-mongodb
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
@Configuration
@Log4j2
@EnableMongoRepositories(basePackages = "<REPOSITORIES_PACKAGE>")
public class MongoConfig extends AbstractMongoConfiguration {
@Value("${DB_HOST}")
private String dbUri;
@Value("${DB_PORT}")
private String port;
@Value("${DB_NAME}")
private String dbName;
@Value("${APP_DIR}")
private String directory;
@Value("${DB_USER}")
private String dbUser;
@Value("${DB_PWD}")
private char[] dbPassword;
private static final String RDS_COMBINED_CA_BUNDLE = "rds-combined-ca-bundle.pem";
@Override
protected String getDatabaseName() {
return db;
}
@Override
public MongoClient mongoClient() {
MongoClient mongoClient = new MongoClient(new ServerAddress(dbUri, Integer.parseInt(port)), mongoCredentials(), mongoClientOptions());
return mongoClient;
}
@Bean
public MongoClientOptions mongoClientOptions() {
MongoClientOptions.Builder mongoClientOptions = MongoClientOptions.builder().sslInvalidHostNameAllowed(true).sslEnabled(true);
try {
String fileName = directory + RDS_COMBINED_CA_BUNDLE;
InputStream is = new FileInputStream(fileName);
// You could get a resource as a stream instead.
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate caCert = (X509Certificate) cf.generateCertificate(is);
TrustManagerFactory tmf = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null); // You don't need the KeyStore instance to come from a file.
ks.setCertificateEntry("caCert", caCert);
tmf.init(ks);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
mongoClientOptions.sslContext(sslContext);
} catch (Exception e) {
log.error(e);
}
return mongoClientOptions.build();
}
private MongoCredential mongoCredentials() {
return MongoCredential.createCredential(dbUser, dbName, dbPassword);
}
}
@ajays0110
Copy link

What is the path for directory in your configuration, because when I am receiving "unable to find valid certification path to requested target" even though I hard coded the file path
@bean
public MongoClientOptions mongoClientOptions() {
MongoClientOptions.Builder mongoClientOptions = MongoClientOptions.builder().sslInvalidHostNameAllowed(true).sslEnabled(true);
try {
String fileName = "/src/main/resources/new-rds.pem";

        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate caCert = (X509Certificate) cf.generateCertificate(Files.newInputStream(Paths.get(fileName)));

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

        tmf.init(ks);

        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);
        mongoClientOptions.sslContext(sslContext);
    } catch (Exception e) {
    }
    return mongoClientOptions.build();
}

@rtehok
Copy link

rtehok commented Nov 28, 2019

For me, I followed the java section of this page with this part:

keytool -importcert -trustcacerts -file rds-combined-ca-bundle.pem -alias rds -keystore rds-ca-certs -storepass <keystorePassword>

and in the code

        String keystore = "rds-ca-certs";
        String keystorePassword = "<keystorePassword>";

        System.setProperty("javax.net.ssl.trustStore", keystore);
        System.setProperty("javax.net.ssl.trustStorePassword", keystorePassword);

Also I downloaded the rds-ca-2019-root.pem and it is working.

@ssi-hu-miklos-kosarkar
Copy link

Hey, have you tried accessing any HTTPS rest endpoint from the same app? I noticed if I have a https call before or after connecting to the documnetdb, all the following connections will fail with SunCertPathBuilderException.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment