我有一个MongoDb
实例正在运行(单个实例)且启用了SSL
。我可以使用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)
我在这里错过了什么,提前谢谢!
答案 0 :(得分:1)
您需要配置monog db驱动程序以使用SSL。您可以在@Configuration类中手动配置它来执行此操作。
{{1}}
答案 1 :(得分:1)
除了使用以下命令导入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");
答案 2 :(得分:1)
下面提到的两种方法通常在论坛上建议' work' 但是不安全,因为他们禁用主机名验证基本上否定了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的证书作为主题备用名称条目,您可以将其导入JDK cacerts
或者,如果您想在应用程序级别建立SSL,我建议为该特定连接创建SSLContext
,而不是使用System.setProperty()
来设置密钥库/信任存储。如果您的应用程序连接到具有不同SSL实现的不同外部服务,这将有助于避免冲突。
特别是对于MongoDB,您只需要在上述步骤之后在MongoDBURI的末尾附加?ssl=true
。如果仍然无效,我建议您按https://jira.mongodb.org/browse/JAVA-2184更新JDK版本
希望这有帮助
答案 3 :(得分:0)
如果将RAD与WAS本地服务器一起使用,则必须将pem文件添加到该服务器的Java VM中。
因此,如果您已将WAS安装到X:\ IBM \ WASx,则X:\ IBM \ WASx \ java_17 \ jre是要导航的目录,然后在其中执行keytool导入。希望这对其他人有帮助。
答案 4 :(得分:0)
如代码中提到的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(true)===> sslEnabled(false)。
答案 5 :(得分:0)
请检查下面的 MongoDB Java驱动程序 4.x和 MongoDB 3.x
代码必须根据您的MongoDB 配置 spring.data.mongodb.xxxx 属性的位置。
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;
}
}