I am consuming a SOAP service using Apache camel Spring-ws component. Things are working fine till the time service was hosted with HTTP protocol.
To work with HTTPS, i tried setting keystore and truststore jks as below
System.setProperty("javax.net.ssl.keyStore",keyStorePath);
System.setProperty("javax.net.ssl.keyStorePassword",keyStorePassword);
System.setProperty("javax.net.ssl.trustStore",trustStorePath);
System.setProperty("javax.net.ssl.trustStorePassword",trustStorePassword);
it fails with the error unable to find the certificate.
Whereas the same properties and jks are working fine when i consume a RESTFull service using Http component.
I could see that the only option currently available is
<camel:sslContextParameters id="sslContextParameters">
<camel:keyManagers keyPassword="password">
<camel:keyStore type="JKS" resource="C:\keystore.jks"
password="changeit" />
</camel:keyManagers>
<camel:trustManagers>
<camel:keyStore type="JKS" resource="C:\keystore.jks"
password="password" />
</camel:trustManagers>
Is there way i can configure it pragmatically, i followed the link below
http://camel.apache.org/http4.html#HTTP4-UsingtheJSSEConfigurationUtility
KeyStoreParameters ksp = new KeyStoreParameters();
ksp.setResource("/users/home/server/keystore.jks");
ksp.setPassword("keystorePassword");
KeyManagersParameters kmp = new KeyManagersParameters();
kmp.setKeyStore(ksp);
kmp.setKeyPassword("keyPassword");
SSLContextParameters scp = new SSLContextParameters();
scp.setKeyManagers(kmp);
HttpComponent httpComponent = getContext().getComponent("https4", HttpComponent.class);
httpComponent.setSslContextParameters(scp);
Supported components are
HTTP4
Jetty
AHC
Netty
Cometd
FTP2
IRC
Mail
MINA 2
But how do i set it for camel-spring-ws component ? Is it currently a limitation with Camel?
Related
I have a server that is sending an HTTPPost request with the Apache HttpClient in Java. I am trying to send the post with my cert attached for validation and the other side is saying they are not receiving anything SSL information. I inherited this code/server setup with minimal documentation so I don't necessarily know it was set up properly in the first place.
Here is the setup.
AWS EC2 server. Linux
Elastic Load balancer setup with SSL Cert.
a. Verified this is working as intended when I visit the server via port 443
Tomcat7 running API server
Java 1.8.0_251
Apache httpclient-4.5.9
Being that there are ways to attach the certificate to each level of this I don't fully understand where the problem is.
Most of the ways I have found revolve around attaching the SSL to the outgoing request in the httpclient object but have been unsuccessful. They are a variation on the following...
KeyStore identityKeyStore = KeyStore.getInstance("JKS");
identityKeyStore.load(identity_file, CERTPASSWORD.toCharArray());
SSLContext sslContext = SSLContexts.custom()
.loadKeyMaterial(identityKeyStore, CERTPASSWORD.toCharArray()).build(); // load client certificate
sslConnectionSocketFactory = new SSLConnectionSocketFactory(
sslContext,
new String[]{"TLSv1.2", "TLSv1.1"},
null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
This has not worked and I have verified the .jks file is properly formatted and verified the password. Although if this works as I test on a windows machine I would assume this would be the best option.
This server only has outgoing requests to a few sources all of which will need to be SSL verified so I don't mind if it is sent on every outgoing https request.
Is there somewhere else in my setup that I should be looking into attaching the certificate?
If there is a Load balancer with SSL configured then the SSL stops at the load balancer, and your client certificate is never making it to the server. Client SSL certificates only get passed to the server when the server has an SSL certificate installed on it, and the load balancer is in TCP passthrough mode.
The service provider who is hosting a rest service is asking to communicate using TLS version 1.2 only.
So now I need to make my application to communicate with that service using TLS v 1.2.
I know, in java8 we have an option of disabling the legacy version of TLS and SSL using the property jdk.tls.disabledAlgorithms=SSLv3, RC4 in java.security file.
But in a server there will be other process using the same java settings, so I'm worried like if I change for that property in java.security file, then it will be applicable to other services which are using the same settings.
Question:
I would like to know if there is any other way to make my rest calls use only particular TLS version, through application code using java/spring libraries ?
Create a SSLContext to use the required protocol:
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, null, null);
If the client code or library uses HttpsURLConnection then you can set the default SSLSocketFactory for all the HTTS Connections:
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
Or at a per connection level:
HttpsURLConnection urlConnection = ....;
urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());
urlConnection.connect();
Different libraries may have different systems to provide the SSLSocketFactory or SSLContext.
For example, if you are using JAX-RS, you can create a REST client that uses the SSLContext with:
Client client = ClientBuilder.newBuilder().sslContext(sslContext).build();
I was using Jersey 2.25 client with Jackson, I configured everything correctly in Jersey, it worked normally on my development machine when I ran it in a test class, but Jersey client could never connect to a certain host that we have when deployed on our STG environment and always throws a read timeout exception.
I also know that the problem is not in our environment because I can connect using curl
But when switched to HTTPClient it worked normally.
This is how we created our Jersey Client:
Client client = ClientBuilder.newBuilder()
.register(JacksonFeature.class)
.property(ClientProperties.CONNECT_TIMEOUT,5000)
.property(ClientProperties.READ_TIMEOUT,15000)
.build();
The only difference here is the flow of the app, and also the major change that happens in the flow that could affect the connection is that somewhere before calling the Jersey client another class sets a proxy in the system config:
System.setProperty("http.proxyHost",strProxyHost);
System.setProperty("http.proxyPort",strProxyPort);
System.setProperty("https.proxyHost",strProxyHost);
System.setProperty("https.proxyPort",strProxyPort);
However we can establish a connection normally using HTTPClient:
HttpConnectionManagerParams params = new HttpConnectionManagerParams();
params.setConnectionTimeout(5000);
params.setSoTimeout(10000);
HttpConnectionManager manager = new SimpleHttpConnectionManager();
manager.setParams(params);
HttpClient httpClient = new HttpClient(manager);
We are using HTTPClient 3 because part of this app is legacy and we cannot update the version, but it works normally.
What could be causing this connection problem with Jersey? is there something global that Jersey reads when it's trying to connect?
Jersey by default uses HttpURLConnection and HttpURLConnection uses following global settings for proxy configuration -
System.setProperty("http.proxyHost",strProxyHost);
System.setProperty("http.proxyPort",strProxyPort);
System.setProperty("https.proxyHost",strProxyHost);
System.setProperty("https.proxyPort",strProxyPort);
It means if these system variables are set, Jersey will send all the requests through this configured proxy. Check Details here
However, Apache HttpClient does not follow these settings. For using proxy in Apache HttpClient, you have to use HostConfiguration class. Check details here
So, now to your problem, It looks that your STG environment is not able to connect to specified proxy but able to connect with the service directly.
So, while using Jersey, client is not able to connect to proxy and hence ReadTimeoutException is occurring. Since, you haven't configured HttpClient for using any proxy, it is able to connect with the service directly.
I'm developing a simple web services using Java EE Servlets.
My clients are a simple java apps (no browsers), so I need to secure my communication using TLS (or SSL v3). About Application server, I'm using Glassfish v3.
For example, I need to transfer some data from client to server within a HTTP Post Request into a secure connection.
There are some external libraries, server configurations or tutorial that can I use?
On the server side you must somehow expose your servlets via HTTPS. If you are using tomcat, check out SSL Configuration HOW-TO. If you have an Apache web server in front, see: Apache SSL/TLS Encryption.
On the client side ssl and https support is built into JDK, just call any https://... address using URLConnection. However remember that the certificate your server uses must be trusted - either confirmed by some authority or added manually on the client. Self-signed certificates by default won't be accepted.
I'm using Apache Axis 1.5.1 to code a web service client connecting to a service over SSL. My application is running in Tomcat with SSL configuration setup in JKS. However, when I connect to the server, the connection is failing because the cert from our client is not being sent to the server. Is this something that has to be set in the client through code? Also note that the server does not need any user name or password authentication. With SSL turned off, everything works fine.
Thanks,
Two common approaches here:
http://ws.apache.org/xmlrpc/ssl.html
WebLogic has its own stuff:
http://download.oracle.com/docs/cd/E12840_01/wls/docs103/security/SSL_client.html#wp1029670
As long as you have the certificates configured correctly in your trust store accessible to Tomcat, there are no changes to Apache Axis HTTP code.