How to override ciphers/protocols programatically on JAX-RS client - ssl

I'm facing issue while trying to override ciphers/protocols on JAX-RS client. Jersey framework is used here.
Following is the way client is built.
Client client = ClientBuilder.newBuilder().sslContext(sslContext).hostnameVerifier(hostnameVerifier).build();
I have tried following approaches, but couldn't succeed.
Created Custom SSLSocketFactory, and override ciphers and protocols on createSocket() method of SSL SocketFactory class.
Then, HttpsURLConnection.setDefaultSSLSocketFactory(sf).
But, its not reflected with this approach.
Tried overriding the sslcontext with help of SslContextFactory & SSLParameters, which also could help.
Could someone help in finding a way to override ciphers/protocols programatically on sslContext of JAX-RS client?

You can implement an SSLSocketFactory :
public class CustomSSLSocketFactory extends SSLSocketFactory {
private final SSLSocketFactory sslSocketFactory;
public CustomSSLSocketFactory(SSLSocketFactory sslSocketFactory) {
this.sslSocketFactory = sslSocketFactory;
}
#Override
public String[] getDefaultCipherSuites() {
return sslSocketFactory.getDefaultCipherSuites();
}
#Override
public String[] getSupportedCipherSuites() {
return sslSocketFactory.getSupportedCipherSuites();
}
#Override
public Socket createSocket() throws IOException {
return adjustEnabledCipherSuites((SSLSocket) sslSocketFactory.createSocket());
}
#Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
return adjustEnabledCipherSuites((SSLSocket) sslSocketFactory.createSocket(socket, host, port, autoClose));
}
#Override
public Socket createSocket(String host, int port) throws IOException {
return adjustEnabledCipherSuites((SSLSocket) sslSocketFactory.createSocket(host, port));
}
#Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
return adjustEnabledCipherSuites((SSLSocket) sslSocketFactory.createSocket(host, port, localHost, localPort));
}
#Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return adjustEnabledCipherSuites((SSLSocket) sslSocketFactory.createSocket(host, port));
}
#Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return adjustEnabledCipherSuites((SSLSocket) sslSocketFactory.createSocket(address, port, localAddress, localPort));
}
private SSLSocket adjustEnabledCipherSuites(SSLSocket sslSocket) {
sslSocket.setEnabledCipherSuites(new String[]{"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"});
return sslSocket;
}
}
Now you need to configure your client to use a custom ConnectionFactory that uses the above SSLSocketFactory :
ClientConfig clientConfig = new ClientConfig()
CustomSSLSocketFactory sslSocketFactory = new CustomSSLSocketFactory(sslContext.getSocketFactory());
HttpUrlConnectorProvider.ConnectionFactory factory = url -> {
HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();
httpsURLConnection.setSSLSocketFactory(sslSocketFactory);
return httpsURLConnection;
};
clientConfig.connectorProvider(new HttpUrlConnectorProvider().connectionFactory(factory));
...
Client client = ClientBuilder.newBuilder().sslContext(sslContext).hostnameVerifier(hostnameVerifier).withConfig(clientConfig).build();

Related

Client Keystore, TrustStore, LDAP Credential

I am having an issue with keystore, truststore, and LDAP credentials for Google.
I am using GraalVM 22.2 on JDK17 for the test.
I created a test class to be able to log into Google LDAP. Once, I figure out how to do it in the test, then I can move it into our application.
I downloaded my Google LDAP credential and key. I then followed the instructions from Google to create a KeyStore:
https://support.google.com/a/answer/9089736?hl=en#other-java-applications
According to Google's instructions, you just add the following to your System properties:
-Djavax.net.ssl.keyStore=[File Path to KeyStore] -Djavax.net.ssl.keyStorePassword=[KeyStore Pass]
-- OR --
System.setProperty("javax.net.ssl.keyStore", "[File Path to KeyStore]");
System.setProperty("javax.net.ssl.keyStorePassword", "[KeyStore Pass]");
The problem with this is we will have a KeyStore with a password that corresponds with a specific LDAP server. This is due to the fact that our application will be able to connect to multiple LDAP servers.
After doing some research, I saw you can create an SSLSocketFactory and set the property "java.naming.ldap.factory.socket". From there, you can add the KeyStore to use via the TrustManager, or KeyManager.
My problem is, when trying to connect to the Google LDAP server; the SSLSocketFactory is completely ignored. How do I know? None of the debugging statements in the SSLSocketFactory, TrustManger, or KeyManager are printed out. (I added a KeyStoreManager for debugging purposes.)
I even tried to import the keystore into cacerts with no luck. In fact, I had multiple problems importing because "keytool" kept complaining about the JKS vs PKCS12 format.
The only way I can connect successfully is to add the 2 System properties. I know I am missing something simple that will explain why it is not working correctly. Anyone got any ideas?
Here is my test class:
import java.io.Console;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.security.KeyStore;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.directory.InitialDirContext;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509KeyManager;
import javax.net.ssl.X509TrustManager;
public class LDAPIT {
public static final String JAVA_NAMING_LDAP_FACTORY_SOCKET = "java.naming.ldap.factory.socket";
public static void main(final String[] args) {
final LDAPIT test = new LDAPIT();
try {
test.run();
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
public void run() throws Exception {
final Console cnsl = System.console();
if (cnsl == null) {
throw new RuntimeException("Console is null");
}
final String url = cnsl.readLine("Enter URL: ");
final String user = cnsl.readLine("Enter username : ");
final String password = String.valueOf(cnsl.readPassword("Enter password : "));
System.out.println("Start Trying to Connect to LDAP: " + url);
System.out.println("With User: " + user);
System.out.println("Creating LDAP Properties");
final Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
props.put(Context.PROVIDER_URL, url);
props.put(Context.SECURITY_PRINCIPAL, user);
props.put(Context.SECURITY_AUTHENTICATION, "simple");
props.put(Context.SECURITY_PROTOCOL, "ssl");
props.put(JAVA_NAMING_LDAP_FACTORY_SOCKET, MySSLSocketFactory.class.getName());
System.out.println("LDAP Properties without password: " + props);
props.put(Context.SECURITY_CREDENTIALS, password);
// System.setProperty("javax.net.ssl.keyStore", "[File Path to KeyStore]");
// System.setProperty("javax.net.ssl.keyStorePassword", "[KeyStore Pass]");
try {
System.out.println("Connecting to LDAP Server");
final InitialDirContext idc = new InitialDirContext(props);
System.out.println("Successfully connected to LDAP");
idc.close();
} catch (final Exception e) {
e.printStackTrace();
}
System.out.println("End Trying to Connect to LDAP");
}
public static class MySSLSocketFactory extends SSLSocketFactory {
private SSLSocketFactory socketFactory;
public MySSLSocketFactory() {
try {
System.out.println("Creating Key Manager");
final MyKeyManager keyManager = new MyKeyManager();
final KeyManager[] keyManagers = {keyManager};
System.out.println("Creating Trust Manager");
final MyTrustManager trustManager = new MyTrustManager();
final TrustManager[] trustManagers = {trustManager};
System.out.println("Creating Socket Context");
final SSLContext ctx = SSLContext.getInstance("TLS");
System.out.println("Initializing Socket Context");
ctx.init(keyManagers, trustManagers, new SecureRandom());
System.out.println("Creating Socket Factory");
socketFactory = ctx.getSocketFactory();
} catch (final Exception ex) {
ex.printStackTrace();
}
}
#Override
public String[] getDefaultCipherSuites() {
return socketFactory.getDefaultCipherSuites();
}
#Override
public String[] getSupportedCipherSuites() {
return socketFactory.getSupportedCipherSuites();
}
#Override
public Socket createSocket(Socket socket, String string, int i, boolean bln) throws IOException {
System.out.println("Creating Socket with: Socket, String, int, Boolean");
return socketFactory.createSocket(socket, string, i, bln);
}
#Override
public Socket createSocket(final Socket s, final InputStream consumed, final boolean autoClose) throws IOException {
System.out.println("Creating Socket with: Socket, InputStream, Boolean");
return super.createSocket(s, consumed, autoClose);
}
#Override
public Socket createSocket() throws IOException {
System.out.println("Creating Socket without parameters");
return super.createSocket();
}
#Override
public Socket createSocket(String string, int i) throws IOException {
System.out.println("Creating Socket with: String ,int");
return socketFactory.createSocket(string, i);
}
#Override
public Socket createSocket(String string, int i, InetAddress ia, int i1) throws IOException {
System.out.println("Creating Socket with: String, int, InetAddress, int");
return socketFactory.createSocket(string, i, ia, i1);
}
#Override
public Socket createSocket(InetAddress ia, int i) throws IOException {
System.out.println("Creating Socket with: InetAddress, int");
return socketFactory.createSocket(ia, i);
}
#Override
public Socket createSocket(InetAddress ia, int i, InetAddress ia1, int i1) throws IOException {
System.out.println("Creating Socket with: InetAddress, InetAddress, int");
return socketFactory.createSocket(ia, i, ia1, i1);
}
}
public static class MyKeyManager implements X509KeyManager {
#Override
public String[] getClientAliases(final String keyType, final Principal[] issuers) {
System.out.println("Getting Client Aliases: String, Principal[]");
return new String[0];
}
#Override
public String chooseClientAlias(final String[] keyType, final Principal[] issuers, final Socket socket) {
System.out.println("Choosing Client Alias: String[], Principal[], Socket");
return null;
}
#Override
public String[] getServerAliases(final String keyType, final Principal[] issuers) {
System.out.println("Getting Server Aliases: String, Principal[]");
return new String[0];
}
#Override
public String chooseServerAlias(final String keyType, final Principal[] issuers, final Socket socket) {
System.out.println("Choosing Server Aliases: String, Principal[], Socket");
return null;
}
#Override
public X509Certificate[] getCertificateChain(final String alias) {
System.out.println("Getting Certificate Chain: String");
return new X509Certificate[0];
}
#Override
public PrivateKey getPrivateKey(final String alias) {
System.out.println("Getting Private Key: String");
return null;
}
}
public static class MyTrustManager implements X509TrustManager {
private X509TrustManager gTrustManager;
public MyTrustManager() {
System.out.println("Creating My Trust Manager");
initTrustManager();
System.out.println("Created My Trust Manager");
}
#Override
public void checkClientTrusted(final X509Certificate[] chain, final String authType) throws CertificateException {
if (gTrustManager != null) {
gTrustManager.checkClientTrusted(chain, authType);
}
}
#Override
public void checkServerTrusted(final X509Certificate[] chain, final String authType) throws CertificateException {
if (gTrustManager != null) {
gTrustManager.checkServerTrusted(chain, authType);
}
}
#Override
public X509Certificate[] getAcceptedIssuers() {
return gTrustManager.getAcceptedIssuers();
}
private void initTrustManager() {
try {
final String keystoreType = KeyStore.getDefaultType();
System.out.println("Loading Keystore Type: " + keystoreType);
KeyStore keyStore = KeyStore.getInstance(keystoreType);
System.out.println("Loading CA Certs");
loadCACerts(keyStore);
System.out.println("Creating SSL Context");
System.out.println("Creating Trust Manager");
gTrustManager = getTrustManager(keyStore);
} catch (final Exception e) {
e.printStackTrace();
}
}
private void loadCACerts(final KeyStore keyStore) throws Exception {
final File keyStoreFile = new File("[File Path to KeyStore]]");
System.out.println("Loading Keystore: " + keyStoreFile.getAbsolutePath());
try (final FileInputStream keyStoreInputStream = new FileInputStream(keyStoreFile)) {
keyStore.load(keyStoreInputStream, "[KeyStore Pass]".toCharArray());
}
System.out.println("Keystore Loaded");
}
private X509TrustManager getTrustManager(final KeyStore k) throws Exception {
final String defaultAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
System.out.println("Loading Trust Manager Algorithm: " + defaultAlgorithm);
final TrustManagerFactory tmf = TrustManagerFactory.getInstance(defaultAlgorithm);
System.out.println("Initializing Trust Manager Factory");
tmf.init(k);
System.out.println("Getting Trust Managers");
final TrustManager[] tms = tmf.getTrustManagers();
int arraySize = 0;
if (tms != null) {
arraySize = tms.length;
}
System.out.println("Iterating through Trust Managers: " + arraySize);
for (final TrustManager tm : tms) {
System.out.println("Trust Manager: " + tm.getClass().getName());
if (tm instanceof final X509TrustManager x509TrustManager) {
System.out.println("Returning X509TrustManager");
return x509TrustManager;
}
}
System.out.println("Could not find correct Trust Manager, returning Null");
return null;
}
}
}
Wouldn't you know it...after I ask the question I figure it out. The answer was you MUST implement the 'getDefault()' method in your custom SSLSocketFactory. I knew it was something simple.
https://docs.oracle.com/javase/jndi/tutorial/ldap/security/ssl.html
Look at Using Custom Sockets.

Using Insecure TLS in Java version of Eclipse Paho

I am trying to connect to an MQTT server without having to validate the TLS certs. I am using the latest version of Eclipse Paho from a Java program. I cannot find a way to turn off the validation.
In the Python version of Eclipse Paho, the vendor who is running the server uses the following code to turn off the validation:
client = mqtt_client.Client(client_id, transport='websockets')
client.tls_set("", cert_reqs=ssl.CERT_NONE)
client.tls_insecure_set(True)
I don't see an equivalent for Java.
Does anyone know how I can accomplish this in Java?
You will need to pass a custom SSLSocketFactory as part of the MqttConnectOptions object passed to the Paho client's connect() method.
This will come from on a SSLContext with a custom TrustManager e.g.
TrustManager [] trustAllCerts = new TrustManager [] {new X509ExtendedTrustManager () {
#Override
public void checkClientTrusted (X509Certificate [] chain, String authType, Socket socket) {
}
#Override
public void checkServerTrusted (X509Certificate [] chain, String authType, Socket socket) {
}
#Override
public void checkClientTrusted (X509Certificate [] chain, String authType, SSLEngine engine) {
}
#Override
public void checkServerTrusted (X509Certificate [] chain, String authType, SSLEngine engine) {
}
#Override
public java.security.cert.X509Certificate [] getAcceptedIssuers () {
return null;
}
#Override
public void checkClientTrusted (X509Certificate [] certs, String authType) {
}
#Override
public void checkServerTrusted (X509Certificate [] certs, String authType) {
}
}};
SSLContext sc = null;
try {
sc = SSLContext.getInstance ("TLS");
sc.init (null, trustAllCerts, new java.security.SecureRandom ());
} catch (KeyManagementException | NoSuchAlgorithmException e) {
e.printStackTrace ();
}
String uri = "ssl://localhost:1884";
String clientId = "client-101";
MqttClient client = new MqttClient(uri, clientId))
final MqttConnectOptions options = new MqttConnectOptions();
options.setSocketFactory(sc.getSocketFactory());
client.connect(options)
This does basically the same as the python code, but you should probably implement some proper checks in the methods in the TrustManager to ensure you are actually connecting to the server you are expecting. Blindly disabling all the checking basically removes a lot of protection of a TLS connection.

How to ignore SSL cert trust errors in Feign?

How can I achieve curl -k in feign client?
I know I can do this. Just want to know if there's a way to ignore or disable.
new Client.Default(SSLSocketFactory sslContextFactory, HostnameVerifier hostnameVerifier)
Disclaimer
You should not actually do this for a number of very good reasons. The easiest way to fix SSL issues is to actually follow SSL best practices and use valid certificates. There are excellent projects online such as https://letsencrypt.org/ that will even allow you to get great security for free if the host is publicly accessible (if it has a real hostname that can be verified against).
USE AT YOUR OWN RISK. MAKE SURE YOU UNDERSTAND YOU ARE VIOLATING A LOT OF BEST PRACTICES AND ONLY USE THIS IF YOU UNDERSTAND THAT.
If you cause some type of major problem using this example code, you are liable.
Real talk
I had the same problem dealing with internal (publicly non-accessible) services that I wanted to call from a spring-boot application and I solved it using the following code.
Brief Overview
A great many people will tell you that you can either accept all certificates, hard-code your particular cert in it, or something else. You can actually allow only certain trusted hosts through the codepath, which is what I am attempting here for an additional layer of security.
In this example code, you can pass multiple hosts to the classes and it should allow requests to only those hosts to be issued with invalid certificates, and everything else will go through the normal chain of command.
This is not really production grade code, but hopefully you will get some use out of it.
Enough lecturing, what follows may interest you the most.
The Code
This is using for Java 8 and spring-boot.
Configuration
#Configuration
public class FeignClientConfiguration {
#Bean
public Client client() throws NoSuchAlgorithmException,
KeyManagementException {
return new Client.Default(
new NaiveSSLSocketFactory("your.host.here"),
new NaiveHostnameVerifier("your.host.here"));
}
}
NaiveHostnameVerifier
public class NaiveHostnameVerifier implements HostnameVerifier {
private final Set<String> naivelyTrustedHostnames;
private final HostnameVerifier hostnameVerifier =
HttpsURLConnection.getDefaultHostnameVerifier();
public NaiveHostnameVerifier(String ... naivelyTrustedHostnames) {
this.naivelyTrustedHostnames =
Collections.unmodifiableSet(
new HashSet<>(Arrays.asList(naivelyTrustedHostnames)));
}
#Override
public boolean verify(String hostname, SSLSession session) {
return naivelyTrustedHostnames.contains(hostname) ||
hostnameVerifier.verify(hostname, session);
}
}
NaiveSSLSocketFactory
public class NaiveSSLSocketFactory extends SSLSocketFactory {
private final SSLSocketFactory sslSocketFactory =
(SSLSocketFactory) SSLSocketFactory.getDefault();
private final SSLContext alwaysAllowSslContext;
private final Set<String> naivelyTrustedHostnames;
public NaiveSSLSocketFactory(String ... naivelyTrustedHostnames)
throws NoSuchAlgorithmException, KeyManagementException {
this.naivelyTrustedHostnames =
Collections.unmodifiableSet(
new HashSet<>(Arrays.asList(naivelyTrustedHostnames)));
alwaysAllowSslContext = SSLContext.getInstance("TLS");
TrustManager tm = new X509TrustManager() {
#Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {}
#Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
#Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
alwaysAllowSslContext.init(null, new TrustManager[] { tm }, null);
}
#Override
public String[] getDefaultCipherSuites() {
return sslSocketFactory.getDefaultCipherSuites();
}
#Override
public String[] getSupportedCipherSuites() {
return sslSocketFactory.getSupportedCipherSuites();
}
#Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
return (naivelyTrustedHostnames.contains(host))
? alwaysAllowSslContext.getSocketFactory().createSocket(socket, host, port, autoClose)
: sslSocketFactory.createSocket(socket, host, port, autoClose);
}
#Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return (naivelyTrustedHostnames.contains(host))
? alwaysAllowSslContext.getSocketFactory().createSocket(host, port)
: sslSocketFactory.createSocket(host, port);
}
#Override
public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) throws IOException, UnknownHostException {
return (naivelyTrustedHostnames.contains(host))
? alwaysAllowSslContext.getSocketFactory().createSocket(host, port, localAddress, localPort)
: sslSocketFactory.createSocket(host, port, localAddress, localPort);
}
#Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return (naivelyTrustedHostnames.contains(host.getHostName()))
? alwaysAllowSslContext.getSocketFactory().createSocket(host, port)
: sslSocketFactory.createSocket(host, port);
}
#Override
public Socket createSocket(InetAddress host, int port, InetAddress localHost, int localPort) throws IOException {
return (naivelyTrustedHostnames.contains(host.getHostName()))
? alwaysAllowSslContext.getSocketFactory().createSocket(host, port, localHost, localPort)
: sslSocketFactory.createSocket(host, port, localHost, localPort);
}
}
References
I borrowed heavily from this answer:
Trusting all certificates using HttpClient over HTTPS
When using Spring Cloud Netflix >= 1.4.4.RELEASE you can also do the following:
Add okhttp client maven dependency:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
And add the following properties:
feign.httpclient.disableSslValidation=true
feign.httpclient.enabled=false
feign.okhttp.enabled=true
Reference:
https://github.com/spring-cloud/spring-cloud-netflix/issues/2729
With current versions of spring-cloud-starter-openfeign suppressing hostname verification works as follows.
When using apache httpclient:
In application.yml set disable-ssl-validation property
feign.httpclient.disable-ssl-validation: true
In pom.xml add feign-httpclient dependency.
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
If you prefer okhttp you must enable okhttp with another application property and add feign-okhttp dependency:
feign.httpclient.disableSslValidation=true
feign.httpclient.enabled=false
feign.okhttp.enabled=true
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
For httpclient5 (hc5), property disable-ssl-validation sadly does not turn off hostname verification (yet?), here's the ticket: https://github.com/spring-cloud/spring-cloud-openfeign/issues/625
Application properties for enabling hc5.
feign.httpclient.disableSslValidation=true
feign.httpclient.hc5.enabled=true
Maven dependency to add
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-hc5</artifactId>
</dependency>
NOTE: The tricky part for me was that I missed to add feign-httpclient as a dependency. In this case, a default feign client with enabled hostname verification is used.
Override via feign configuration
#Bean
public Client feignClient()
{
Client trustSSLSockets = new Client.Default(getSSLSocketFactory(), new NoopHostnameVerifier());
return trustSSLSockets;
}
private SSLSocketFactory getSSLSocketFactory() {
try {
TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
#Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
};
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
return sslContext.getSocketFactory();
} catch (Exception exception) {
}
return null;
}
feign.httpclient.disableSslValidation = true is not worked for me.
Create Client bean in Configuration by the following code is worked:
import feign.Client;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.ssl.SSLContexts;
import org.springframework.context.annotation.Bean;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
public class ClientConfiguration {
#Bean
public Client feignClient() {
return new Client.Default(getSSLSocketFactory(), new NoopHostnameVerifier());
}
private SSLSocketFactory getSSLSocketFactory() {
try {
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();
return sslContext.getSocketFactory();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
pom.xml might needs add dependencies:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.8</version>
</dependency>
Disable ssl Validation by adding below property in application.yaml.
feign.httpclient.disableSslValidation=true
or as a VM argument
-Dfeign.httpclient.disableSslValidation=true
Add below class to your repository and use this class as configuration
this piece of code worked for me:
#Configuration
public class SSLSocketClient {
#Bean
public Client feignClient() {
return new Client.Default(getSSLSocketFactory(),getHostnameVerifier());
}
//SSLSocketFactory
// Install the all-trusting trust manager
public static SSLSocketFactory getSSLSocketFactory() {
try {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, getTrustManager(), new SecureRandom());
return sslContext.getSocketFactory();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
//TrustManager
// trust manager that does not validate certificate chains
private static TrustManager[] getTrustManager() {
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
#Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
#Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
#Override
public X509Certificate[] getAcceptedIssuers()
{
return new X509Certificate[]{};
}
}};
return trustAllCerts;
}
//HostnameVerifier
public static HostnameVerifier getHostnameVerifier() {
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
#Override
public boolean verify(String s, SSLSession sslSession)
{
return true;
}
};
return hostnameVerifier;
}}

Dropwizard client deal with self signed certificate

Quite new with Dropwizard.
I found a lot of solution to deal with Jersey and ssl self signed certificate.
Dropwizard version is 0.9.2
I have tried to set a SSLContext but I get
The method sslContext(SSLContext) is undefined for the type JerseyClientBuilder
Code:
TrustManager[] certs = new TrustManager[]{
new X509TrustManager() {
#Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
#Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
#Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
}
};
public static class TrustAllHostNameVerifier implements HostnameVerifier {
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
private Client getWebClient(AppConfiguration configuration, Environment env) {
SSLContext ctx = SSLContext.getInstance("SSL");
ctx.init(null, certs, new SecureRandom());
Client client = new JerseyClientBuilder(env)
.using(configuration.getJerseyClient())
.sslContext(ctx)
.build("MyClient");
return client;
}
The configuration part:
private JerseyClientConfiguration jerseyClient = new JerseyClientConfiguration();
public JerseyClientConfiguration getJerseyClient() {
return jerseyClient;
}
I have found a simple solution just using the configuration
jerseyClient:
tls:
verifyHostname: false
trustSelfSignedCertificates: true
I think to create an insecure client in 0.9.2 you would use a Registry of ConnectionSocketFactory, something like...
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[] { new X509TrustManager() {
#Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
throws java.security.cert.CertificateException {
}
#Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
throws java.security.cert.CertificateException {
}
#Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
} }, new SecureRandom());
final SSLConnectionSocketFactory sslConnectionSocketFactory =
new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
final Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslConnectionSocketFactory)
.register("http", PlainConnectionSocketFactory.INSTANCE)
.build();
builder.using(registry);
Client client = new JerseyClientBuilder(env)
.using(configuration.getJerseyClient())
.using(registry)
.build("MyInsecureClient");

Camel iMap - ignore SSL certificat

i'm using imap endpoint and i try to ignore SSL certificat by using:
the First class DummySSLSocketFactory :
public class DummySSLSocketFactory extends SSLSocketFactory {
private SSLSocketFactory factory;
public DummySSLSocketFactory() {
try {
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null,
new TrustManager[] { new
DummyTrustManager()},
null);
factory = (SSLSocketFactory)sslcontext.getSocketFactory();
} catch(Exception ex) {
// ignore
}
}
public static SocketFactory getDefault() {
return new DummySSLSocketFactory();
}
public Socket createSocket() throws IOException {
return factory.createSocket();
}
public Socket createSocket(Socket socket, String s, int i, boolean flag)
throws IOException {
return factory.createSocket(socket, s, i, flag);
}
public Socket createSocket(InetAddress inaddr, int i,
InetAddress inaddr1, int j) throws IOException {
return factory.createSocket(inaddr, i, inaddr1, j);
}
public Socket createSocket(InetAddress inaddr, int i)
throws IOException {
return factory.createSocket(inaddr, i);
}
public Socket createSocket(String s, int i, InetAddress inaddr, int j)
throws IOException {
return factory.createSocket(s, i, inaddr, j);
}
public Socket createSocket(String s, int i) throws IOException {
return factory.createSocket(s, i);
}
public String[] getDefaultCipherSuites() {
return factory.getDefaultCipherSuites();
}
public String[] getSupportedCipherSuites() {
return factory.getSupportedCipherSuites();
}
}
the second class DummyTrustManager :
public class DummyTrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] cert, String authType) {
// everything is trusted
}
public void checkServerTrusted(X509Certificate[] cert, String authType) {
// everything is trusted
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
the third class AllowAll to set java mail propeties:
public class AllowAll {
public void setsslproperties() {
//DummySSLSocketFactory easy = new EasySSLProtocolSocketFactory();
Properties props = System.getProperties();
props.setProperty("mail.imap.ssl.enable", "true");
props.setProperty("mail.imap.ssl.socketFactory.class","com.mycompany.imapssl.DummySSLSocketFactory");
props.setProperty("mail.imap.ssl.socketFactory.fallback", "false");
props.setProperty("mail.imap.socketFactory.port", "993");
Session session = Session.getInstance(props, null);
}
}
How can i associate this to the iMap EiP to ignore SSL Certificate ?
this is the route:
<route id="timerToLog">
<from uri="imaps://server:993?username=user_name&password=pass"/>
<log message="ok"/>
If you're using a recent version of JavaMail, set the mail.imap.ssl.trust property to the name of the host you want to trust. That avoids the need to create your own socket factory.