Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set a certificate to be trusted for a spring RestTemplate

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.

like image 909
Filip Majernik Avatar asked Jan 04 '12 17:01

Filip Majernik


People also ask

How do I bypass SSL in RestTemplate?

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.


2 Answers

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/

like image 73
GeertPt Avatar answered Sep 19 '22 13:09

GeertPt


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.

like image 43
Mariano L Avatar answered Sep 21 '22 13:09

Mariano L