簡體   English   中英

如何在 Java 11 客戶端 - MongoDB 4.4 (SSL) 之間進行身份驗證?

[英]How to authenticate between a Java 11 Client - MongoDB 4.4 (SSL)?

我被要求將 Java 8(彈簧)微服務遷移到 Java 11 微服務(Quarkus 框架)。 微服務使用 X509 證書對 MongoDB 4.4 數據庫進行身份驗證。 這適用於 Java 8 版本,沒有任何錯誤或問題。 盡管如此,Java 11 版本將無法工作,並且在部署時會顯示以下堆棧跟蹤:

  com.mongodb.MongoSocketWriteException: Exception sending message
        at com.mongodb.internal.connection.InternalStreamConnection.translateWriteException(InternalStreamConnection.java:619)
        at com.mongodb.internal.connection.InternalStreamConnection.sendMessage(InternalStreamConnection.java:497)
        at com.mongodb.internal.connection.InternalStreamConnection.sendCommandMessage(InternalStreamConnection.java:328)
        at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:278)
        at com.mongodb.internal.connection.CommandHelper.sendAndReceive(CommandHelper.java:83)
        at com.mongodb.internal.connection.CommandHelper.executeCommand(CommandHelper.java:33)
        at com.mongodb.internal.connection.InternalStreamConnectionInitializer.initializeConnectionDescription(InternalStreamConnectionInitializer.java:107)
        at com.mongodb.internal.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:62)
        at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:144)
        at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.lookupServerDescription(DefaultServerMonitor.java:188)
        at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:144)
        at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: javax.net.ssl.SSLHandshakeException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors

相關源代碼:

package everest.onecd.config;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoDatabase;

public class MongoConfiguration  {
    
    private static final String PATH = "/usr/share/easy-rsa/keys/java11/mongo.jks";
    
    private static final Logger LOG = LoggerFactory.getLogger(MongoConfiguration.class);
            
    private static final String IP = "XX.XX.XX.XX";
    
    private static final String PORT = "27017";

    public static MongoDatabase getDatabase() {
        SSLContext context = getSSLContext();
        MongoClientSettings.Builder settings = MongoClientSettings.builder();
        settings.applyToSslSettings(builder -> { builder.context(context); builder.invalidHostNameAllowed(true); builder.enabled(true); });
        settings.applyConnectionString(new ConnectionString("mongodb://" + IP +  ":" + PORT + "/test?ssl=true&authMechanism=MONGODB-X509&connectTimeoutMS=60000&socketTimeoutMS=60000&retryWrites=true&maxIdleTimeMS=60000"));                      
        MongoClient client = MongoClients.create(settings.build());     
        MongoDatabase database = client.getDatabase("test");        
        return database;
    }

    private static SSLContext getSSLContext() {
        SSLContext sslContext = null;
            try (FileInputStream fis = new FileInputStream(new File(PATH))) {                               
                KeyStore keyStore = KeyStore.getInstance("JKS");
                keyStore.load(fis, ".sevenzip".toCharArray());
                TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                trustManagerFactory.init(keyStore);
                sslContext = SSLContext.getInstance("SSL");
                sslContext.init(null, trustManagerFactory.getTrustManagers(), null);        
                LOG.info("Se ejecuto SSLContext exitosamente");
            } catch (CertificateException | NoSuchAlgorithmException | KeyStoreException | IOException | KeyManagementException e) {
                LOG.error(e.toString(), e);         
            } 
        return sslContext;
    }
}
    

I already tried this: Java 11 and 12 SSL sockets fail on a handshake_failure error with TLSv1.3 enabled So, I generated the new JKS with -keyalg RSA but it didn't work either. 我還將 TLS 版本更改為 1.2 和 1.3 並得到了相同的異常。

這是解決方案,畢竟斗爭。 在 Quarkus 中,需要對所有的信任庫和密鑰庫進行完全初始化。 因此,顯然,它忽略了 JVM args -Djavax.net.ssl.keyStore 和 -Djavax.net.ZF9D5C16A7F42203F8C175432.354A。

private static SSLContext getSSLContext() {
    SSLContext sslContext = null;
        try (FileInputStream fis = new FileInputStream(new File(TPATH))) {                              
            KeyStore trustStore = KeyStore.getInstance("JKS");
            trustStore.load(fis, ".sevenzip".toCharArray());
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(trustStore);
            
            FileInputStream fKS = new FileInputStream(new File(PATH));
            KeyStore keyStore = KeyStore.getInstance("JKS");
            keyStore.load(fKS, ".sevenzip".toCharArray());
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(keyStore, ".sevenzip".toCharArray());
            
            sslContext = SSLContext.getInstance("SSL");
            sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
            
            LOG.info("Se ejecuto SSLContext exitosamente");
        } catch (CertificateException | NoSuchAlgorithmException | KeyStoreException | IOException | KeyManagementException e) {
            LOG.error(e.toString(), e);         
        } catch (UnrecoverableKeyException e) {
            LOG.error(e.toString(), e);             
        } 
    return sslContext;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM