I am using Spring RestTemplate in my application to access external web services. This web service hat SSL enabled, however, with a self signed certificate (domain, etc... are also not valid). This is just on a local network, so I do not have to be worry about some security issues. I want to make Spring to accept this certificate. This is what I've done so far:
1.) I have configured my JBOSS 7 to use this keystore
<connector name="https" protocol="HTTP/1.1" socket-binding="https" scheme="https" enable-lookups="false" secure="true">
<ssl name="ssl" key-alias="my-private-key" password="rmi+ssl" certificate-key-file="../standalone/configuration/server-keystore.jks" protocol="TLSv1" verify-client="false"/>
</connector>
2.) Here is the configuration of my RestTemplate Bean (I am using autowireing in my classes)
<bean id="stringHttpConverter" class="org.springframework.http.converter.StringHttpMessageConverter"></bean>
<bean id="httpClientParams" class="org.apache.commons.httpclient.params.HttpClientParams">
<property name="authenticationPreemptive" value="true"/>
<property name="connectionManagerClass" value="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager"/>
</bean>
<bean id="httpClient" class="org.apache.commons.httpclient.HttpClient">
<constructor-arg ref="httpClientParams"/>
</bean>
<bean id="httpClientFactory" class="org.springframework.http.client.CommonsClientHttpRequestFactory">
<constructor-arg ref="httpClient"/>
</bean>
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<constructor-arg ref="httpClientFactory"/>
<property name="messageConverters">
<list>
<!-- <ref bean="marshallingConverter" /> -->
<ref bean="stringHttpConverter" />
</list>
</property>
</bean>
I have imported the server certificate into the keystore, it is definitely in there. What else do I have to do? I've already checked all similar questions here, but none of them helped. Thanks.
To skip or avoid the SSL check, we need to modify the default RestTemplate available with the normal Spring package. In this configuration class, we basically declare a new Bean that creates a HTTPClient with the certificate check as disabled.
The server-keystore.jks that you specified in the connector for jboss-web is only used as server certificate for incoming connections.
For outbound connections, JBoss acts like any other java client, so you need to import the server certificate into the default java truststore. You could use the default %JAVA_HOME%\lib\security\cacerts, and import your server certificate using:
keytool -import -trustcacerts -keystore cacerts -storepass changeit -noprompt -alias mycert -file mycert.cer
If you don't want to edit the default cacerts, you could define an alternative truststore by setting system properties like explained in: Java client certificates over HTTPS/SSL.
A third way is to override the https ProtocolSocketFactory so that it accepts all certificates, like: http://drumcoder.co.uk/blog/2011/mar/30/httpclient-self-signed-certificates/
I made a simple method:
static HttpComponentsClientHttpRequestFactory requestFactory = null;
/**
*
* @return
*/
public static ServerProperties getServerProperties() {
return serverProperties;
}
/**
* @return
*/
public static HttpComponentsClientHttpRequestFactory getRequestFactory() {
if (requestFactory == null) {
TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
return true;
}
};
SSLContext sslContext = null;
try {
sslContext = org.apache.http.ssl.SSLContexts.custom()
.loadTrustMaterial(null, acceptingTrustStrategy)
.build();
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(csf)
.build();
requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
}
}
return requestFactory;
}
Then when I instance restTemplate:
RestTemplate restTemplate = new RestTemplate(getRequestFactory());
Simple.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With