Skip to content

Instantly share code, notes, and snippets.

@giner
Last active August 28, 2024 14:38
Show Gist options
  • Save giner/36e3798e659fb48657afe7fc1df0d4b3 to your computer and use it in GitHub Desktop.
Save giner/36e3798e659fb48657afe7fc1df0d4b3 to your computer and use it in GitHub Desktop.
Java: Feign Client mTLS (by enabling custom keystore and truststore for a specific enpoint)
// How to test
//
// Update uriPrefix, keystoreFile, keystorePassword, truststoreFile, truststorePassword with your values and run:
// curl -L -O https://repo1.maven.org/maven2/io/github/openfeign/feign-core/11.6/feign-core-11.6.jar
// java -cp feign-core-11.6.jar HelloFeignmTLS.java
// Feign
import feign.Feign;
import feign.RequestLine;
// Required for mTLS
import feign.Client;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyStore;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.KeyManagerFactory;
public class HelloFeignmTLS {
private static final String uriPrefix = "https://10.10.10.10.nip.io"; // Server protected by mTLS
private static final String keystoreFile = "/path/to/client.pkcs12";
private static final String keystorePassword = "<keystorepass>";
private static final String truststoreFile = "/path/to/truststore.pkcs12";
private static final String truststorePassword = "<truststorepass>";
public static void main(String... args) throws Exception {
SSLSocketFactory sslSocketFactory = sslSocketFactory(keystoreFile, keystorePassword, truststoreFile, truststorePassword);
MyClient myClient = Feign.builder()
.client(new Client.Default(sslSocketFactory, null))
.target(MyClient.class, uriPrefix);
String response = myClient.getRoot();
System.out.println(response);
}
interface MyClient {
@RequestLine("GET /")
String getRoot();
}
private static SSLSocketFactory sslSocketFactory(
String keystoreFile,
String keystorePassword,
String truststoreFile,
String truststorePassword)
throws Exception {
// Keystore
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
try (InputStream in = new FileInputStream(keystoreFile)) {
keystore.load(in, keystorePassword.toCharArray());
}
KeyManagerFactory keyManagerFactory =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keystore, keystorePassword.toCharArray());
// Truststore
KeyStore truststore = KeyStore.getInstance(KeyStore.getDefaultType());
try (InputStream in = new FileInputStream(truststoreFile)) {
truststore.load(in, truststorePassword.toCharArray());
}
TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(truststore);
// SSLContext
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(
keyManagerFactory.getKeyManagers(),
trustManagerFactory.getTrustManagers(),
null);
return sslContext.getSocketFactory();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment