Search code examples
javassljks

Is there a way to configurate a SSL certificate in Azure Kubernetes Service using WebFlux without use a Java keyStore?


I have a microservice deploy in AKS plataform and this microservice has to connect an external API that uses a SSL certificates. My doubt if there's a way to configurates the SSL certificate without use a java Keystore, my project is develop in Java language using Spring boot with WebFlux. I found a example that how can use a jks file and Webflux but not working.

I uses the next code to generates a SslContext:

public  SslContext getSslContext(){
 SslContext sslContext;  
 try {  
   KeyStore ks = KeyStore.getInstance("JKS");
   try (InputStream is = getClass().getResourceAsStream("/my- 
   truststore.jks")) 
  {
     ks.load(is, "truststore-password".toCharArray());
  }
  X509Certificate[] trusted = 
  Collections.list(ks.aliases()).stream().map(alias -> {
     try {
         return (X509Certificate) ks.getCertificate(alias);
     } catch (KeyStoreException e) {
         throw new RuntimeException(e);
     }
  }).toArray(X509Certificate[]::new);
  sslContext = SslContextBuilder.forClient().trustManager(trusted).build();
 } catch (GeneralSecurityException | IOException e) {
  throw new RuntimeException(e);
 }
}

And I uses the next to generate a WebClient:

public  WebClient getSslWebClient (){

    try {

        sslContext = getSslContext();

    } catch (Exception e) {

        e.printStackTrace();
    }
    SslContext finalSslContext = sslContext;
    TcpClient tcpClient = TcpClient.create().secure(sslContextSpec -> 
                          sslContextSpec.sslContext(finalSslContext));
    HttpClient httpClient = HttpClient.from(tcpClient);
    ClientHttpConnector httpConnector = new 
                                      ReactorClientHttpConnector(httpClient);   
    return WebClient.builder().clientConnector(httpConnector).build();
}

I appreciate your support in advance. Regards.


Solution

  • Well, after days of research, I found a way to use a certificate without using the Java KeyStore (JKS). For this, I need the certificate in PEM format, then copy this certificate as a property in the parameter file and then invoke it directly:

    public class SslConfig {
    
    @Value("${ocp.http-client.certificate}")
    private  String certificate;
    
    private final static String certificateType = "X.509";
    private final static String alias = "root";
    
    private static SslContext sslContext;
    
    public  WebClient getSslWebClient (){
    
        try {
    
            sslContext = getSslContext();
    
        } catch (Exception e) {
    
            e.printStackTrace();
        }
        SslContext finalSslContext = sslContext;
        TcpClient tcpClient = TcpClient.create().secure(sslContextSpec -> sslContextSpec.sslContext(finalSslContext));
        HttpClient httpClient = HttpClient.from(tcpClient);
        ClientHttpConnector httpConnector = new ReactorClientHttpConnector(httpClient);
    
        return WebClient.builder().clientConnector(httpConnector).build();
    }
    
    //Se configura el contexto sobre el cual se trabajara la comunicacion SSL
    public  SslContext getSslContext(){
    
        try {
            ByteArrayInputStream is = new ByteArrayInputStream(certificate.getBytes());
            final KeyStore keyStore = readKeyStore(is);
    
            X509Certificate[] trusted = Collections.list(keyStore.aliases()).stream().map(alias -> {
                try {
                    return (X509Certificate) keyStore.getCertificate(alias);
                } catch (KeyStoreException e) {
                    System.out.println(e.getMessage());
                    throw new RuntimeException(e);
    
                }
            }).toArray(X509Certificate[]::new);
            sslContext = SslContextBuilder.forClient().trustManager(trusted).build();
        }catch (GeneralSecurityException | SSLException e ){
            System.out.println(e.getMessage());
            throw new RuntimeException(e);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sslContext;
    }
    
    private static KeyStore readKeyStore(InputStream is) throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException {
    
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(null, null);
        CertificateFactory cf = CertificateFactory.getInstance(certificateType);
        Certificate cert = null;
        while (is.available() > 0) {
            cert = cf.generateCertificate(is);
        }
        ks.setCertificateEntry(alias, cert);
        return ks;
    }
    }
    

    After this, I can make a request and get the response what I need.