从JAVA应用程序使用SSL连接到MongoDb

amrnrhlw  于 2022-11-14  发布在  Java
关注(0)|答案(8)|浏览(213)

我有一个启用了SSLMongoDb示例正在运行(单示例)。我可以使用RoboMongo连接到它,在SSL选项卡上我提供了以下内容:

CA File : /path to my certificate/testCA.pem 
PEM certificate/key: /path to my key/testKey.pem

现在我尝试从java应用程序连接到同一个mondodb。我使用以下命令将testCA.pem导入到cacerts中:

keytool -import -keystore cacerts -file testCA.pem -storepass changeit

我可以看到一个新的条目添加到存储中。试图添加另一个密钥到它,它说无效的证书。在Java应用程序上,我设置系统属性如下:

System.setProperty ("javax.net.ssl.trustStore","C:\\Program Files\\Java\\jre1.8.0_91\\lib\\security\\cacerts");
System.setProperty ("javax.net.ssl.trustStorePassword","changeit");

我得到了以下错误:

org.springframework.dao.DataAccessResourceFailureException: Timed out after 10000 ms while waiting to connect. Client view of cluster state is {type=Unknown, servers=[{address=test.mongo.com:27017, type=Unknown, state=Connecting, exception={com.mongodb.MongoException$Network: Exception opening the socket}, caused by {java.io.EOFException}}]; nested exception is com.mongodb.MongoTimeoutException: Timed out after 10000 ms while waiting to connect. Client view of cluster state is {type=Unknown, servers=[{address=test.mongo.com:27017, type=Unknown, state=Connecting, exception={com.mongodb.MongoException$Network: Exception opening the socket}, caused by {java.io.EOFException}}]
    at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:75)
    at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:2075)
    at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:1918)

我在这里错过了什么,提前感谢!

ukxgm1gy

ukxgm1gy1#

除了使用以下命令导入CAFile.pem之外:
(导航到您的java_home/jre/lib/security以运行命令)
1. keytool -import -trustcacerts -file testCA.pem -keystore cacerts -storepass "changeit"
我还必须将key.pem导出为pkcs12(默认密码为'changeit'
2. openssl pkcs12 -export -out mongodb.pkcs12 -in testKey.pem
并且除了设置系统属性trustStore/password之外,还应该设置keyStore/password:

System.setProperty ("javax.net.ssl.trustStore",JAVA_HOME + "\\lib\\security\\cacerts");
System.setProperty ("javax.net.ssl.trustStorePassword","changeit");
System.setProperty ("javax.net.ssl.keyStore",JAVA_HOME + "\\lib\\security\\mongodb.pkcs12");
System.setProperty ("javax.net.ssl.keyStorePassword","changeit");
dvtswwa3

dvtswwa32#

下面提到的两种方法通常在论坛上建议 “工作”,但不安全,因为它们禁用主机名验证,实质上否定了SSL。因此,不推荐它们,特别是如果您的代码将部署在生产上:

// 1. For any HTTPS connection
    javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
        new javax.net.ssl.HostnameVerifier(){
            public boolean verify(String hostname,
                javax.net.ssl.SSLSession sslSession) {
                    if(hostname.equals("<hostname>")) {
                        return true; 
                    }
                }
            });

// 2. MongoDB SSL specific 
MongoClientOptions.builder().sslEnabled(true).sslInvalidHostNameAllowed(true).build();

参考:https://wiki.openssl.org/index.php/Hostname_validation
要解决这个问题,您需要一个包含服务器DNS的证书作为Subject Alternative Name条目,您可以将其导入到JDK cacerts
或者,如果您希望在应用程序级别建立SSL,我建议为该特定连接创建一个SSLContext,而不是使用System.setProperty()来设置密钥库/信任库。如果您的应用程序连接到具有不同SSL实现的不同外部服务,这将有助于避免冲突。
特别是对于MongoDB,您只需要在上面提到的步骤之后在MongoDBURI的末尾追加?ssl=true即可。
希望这对你有帮助

oxalkeyp

oxalkeyp3#

您需要配置monog db驱动程序以使用SSL。您可以在@Configuration类中手动配置它。

public @Bean MongoClient mongo()  {
        MongoClientOptions.Builder options = MongoClientOptions.builder().sslEnabled(true);
        // add more options to the builder with your config
        MongoClient mongoClient = new MongoClient("localhost", options.build());
        return mongoClient;
    }
egmofgnx

egmofgnx4#

如果将RAD与WAS本地服务器一起使用,则必须将pem文件添加到该服务器的java VM中。
因此,如果您已经将WAS安装到X:\IBM\WASx,那么X:\IBM\WASx\java_17\jre就是您要导航的目录,然后在那里执行keytool导入。希望这对其他人有所帮助。

6yjfywim

6yjfywim5#

请检查MongoDB Java驱动程序4.x和MongoDB3.x的以下代码
在这里你必须配置 * spring.data.mongodb.xxxx * 属性作为你的MongoDB

import java.util.Arrays;
import java.util.List;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.mongodb.MongoClientSettings;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;

@Configuration
public class MongoClientConfig {

    @Value("${spring.data.mongodb.username}")
    private String user;
    
    @Value("${spring.data.mongodb.password}")
    private char[] password;
    
    @Value("${spring.data.mongodb.host}")
    private String host;
    
    @Value("${spring.data.mongodb.port}")
    private int port;
    
    @Value("${spring.data.mongodb.database}")
    private String database;
    
    @Bean
    public MongoClient mongo() {
        List<ServerAddress> hosts = Arrays.asList(new ServerAddress(host, port));
        MongoCredential credential = MongoCredential.createCredential(user, database, password);

        MongoClientSettings settings = MongoClientSettings.builder().credential(credential)
                .applyToSslSettings(builder -> builder.enabled(true))
                .applyToClusterSettings(builder -> builder.hosts(hosts)).build();
        MongoClient mongoClient = MongoClients.create(settings);
        System.out.println("====================================================================");
        System.out.println("========= MongoClientConfig: " + mongoClient.toString() + "=========");
        System.out.println("====================================================================");
        return mongoClient;
    }
}
cdmah0mi

cdmah0mi6#

1.我从here下载了一个openssl程序并安装了它
1.我在我的Pem文件certiface.pem的文件夹中打开了一个cmd
然后我运行一个命令:
导出-输出密钥库. pkcs 12-输入证书.pem
在密码上输入您想要内容,例如:blabla应创建一个名为keystore.pkcs12的文件
1.在cmd上运行命令
密钥工具-导入密钥库-源密钥库密钥库. pkcs 12-源存储类型PKCS 12-目标密钥库密钥库.jks -目标存储类型JKS
在密码我把blabla检查创建的文件keystore.jks
1.现在我代码

System.setProperty("javax.net.ssl.keyStore", keystore.jks);
      System.setProperty("javax.net.ssl.keyStorePassword", "blabla");
      MongoClient mongoClient = MongoClients.create("mongodb+srv://YOURLINK.mongodb.net/?authSource=%24external&authMechanism=MONGODB-X509&retryWrites=true&w=majority");
      database = mongoClient.getDatabase("DatabaseName");
h7wcgrx3

h7wcgrx37#

下面是如何使用mongoUri和sslCertificates通过ssl连接到MongoDB/DocDB的完整实现。在这个实现中,应用程序自己创建密钥库文件,并将证书导入其中。因此,在大多数情况下,不需要做任何服务器端的更改。https://github.com/BarathArivazhagan/spring-boot-aws-documentdb

qni6mghb

qni6mghb8#

正如Redlab在代码中提到的,它可以被禁用以限制ssl验证。特别是这种情况下出现在本地安装中。不需要额外的工作。

public @Bean MongoClient mongo()  {
    MongoClientOptions.Builder options = MongoClientOptions.builder().sslEnabled(false);
    // add more options to the builder with your config
    MongoClient mongoClient = new MongoClient("localhost", options.build());
    return mongoClient;
}

-- sslEnabled(真)===〉sslEnabled(假)。

相关问题