Reputation: 41
I have a requirement to temporarily disable certificate validation in Camel 2.12. I am referencing a test web service that is currently supplying an invalid certificate and getting the following exception -
Exception in route: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Many of the example I've found on SO revolve around creating an HttpClientConfigurer and doing this -
SSLContext ctx = SSLContext.getInstance("SSL");
ctx.init(null, new TrustManager[] { tm }, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx,
SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = client.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https4", 443, ssf));
These solutions require a version of the configureHttpClient(HttpClient hc) method that takes an org.apache.http.client.HttpClient. In my Camel version, this method takes an org.apache.commons.httpclient.HttpClient, and has no reference to getConnectionManager().
I've tried the JVM setting com.sun.net.ssl.checkRevocation=false, but this has no effect.
Upvotes: 4
Views: 10550
Reputation: 68
I have disabled validation as follows:
import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.http4.HttpComponent;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.util.jndi.JndiContext;
import org.apache.camel.util.jsse.KeyStoreParameters;
import org.apache.camel.util.jsse.SSLContextParameters;
import org.apache.camel.util.jsse.TrustManagersParameters;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
public class Sample {
public static void main(String args[]) throws Exception{
JndiContext jndiContext = new JndiContext();
jndiContext.bind("x509HostnameVerifier", new AllowAllHostnameVerifier());
CamelContext context = new DefaultCamelContext(jndiContext);
context.addRoutes(new RouteBuilder() {
private void configurate(){
KeyStoreParameters trust_ksp = new KeyStoreParameters();
trust_ksp.setResource("keystore/keystore.jks");
trust_ksp.setPassword("qweqwe");
TrustManagersParameters trustp = new TrustManagersParameters();
trustp.setKeyStore(trust_ksp);
SSLContextParameters scp = new SSLContextParameters();
scp.setTrustManagers(trustp);
HttpComponent httpComponent = getContext().getComponent("https4", HttpComponent.class);
httpComponent.setSslContextParameters(scp);
}
public void configure() throws Exception {
configurate();
from("file://test_folder")
.setHeader("SOAPAction", constant("/Action"))
.to("https4://localhost?x509HostnameVerifier=x509HostnameVerifier&authUsername=user&authPassword=pasword");
}
});
context.start();
Thread.sleep(600000);
context.stop();
}
Upvotes: -2
Reputation: 41
OK, I finally managed to get this to work - thanks to the many postings out there that helped with some of the detail of what I was attempting to do, particular thanks to this posting. Step by step using Camel 2.12.1 -
My secure URL behind a proxy -
https4://someURL?proxyAuthHost=proxy.company.com&proxyAuthPort=8080&proxyAuthScheme=http
Creating the component to access the URL -
import org.apache.camel.component.http4.HttpComponent;
...
final HttpComponent myComponent = new HttpComponent();
myComponent.setClientConnectionManager(new PoolingClientConnectionManager());
myComponent.setHttpClientConfigurer(new myHttpClientConfigurer());
Note: the need to set a ClientConnectionManager only became clear when the code threw a NPE in HttpComponent at line 317 -
SchemeRegistry registry = clientConnectionManager.getSchemeRegistry();
myHttpClientConfigurer.java
import org.apache.camel.component.http4.HttpClientConfigurer;
import org.apache.http.client.HttpClient;
...
public class myHttpClientConfigurer implements HttpClientConfigurer {
@Override
public void configureHttpClient(HttpClient hc) {
try {
Properties properties = loadProperties();
KeyStore trustStore = KeyStore.getInstance("JKS");
final String javaKeystoreFile = getJavaKeystoreFile(properties);
final String keystorePassword = getKeystorePassword(properties);
trustStore.load(new FileInputStream(javaKeystoreFile), keystorePassword.toCharArray());
KeyManagerFactory keyFactory = KeyManagerFactory.getInstance("SunX509");
keyFactory.init(trustStore, keystorePassword.toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance("SunX509");
trustFactory.init(trustStore);
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(keyFactory.getKeyManagers(), trustFactory.getTrustManagers(), null);
TrustStrategy trustStrategy = new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
};
SSLSocketFactory factory = new SSLSocketFactory(SSLSocketFactory.TLS, trustStore, keystorePassword, trustStore, null, trustStrategy, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
SchemeRegistry registry = hc.getConnectionManager().getSchemeRegistry();
registry.register(new Scheme("https", 443, factory));
catch ...
}
Note that although the URL specifies "https4", the new Scheme() is "https". This seemed to be the only way I could get it to work, after stepping though the HttpComponent code in the debugger.
Upvotes: 0
Reputation: 3291
I think you are using camel-http component, you need to use camel-http4 component instead.
Upvotes: 0