/** * */ package fr.cedrik.spring.http.client; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.security.GeneralSecurityException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import javax.annotation.PostConstruct; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManagerFactory; import org.apache.commons.io.IOUtils; import org.springframework.http.client.ClientHttpRequest; /** * Note: does not do authentication; this can be added to the returned {@link ClientHttpRequest}'s headers. * * @author Cédrik LIME */ public class SSLSimpleClientHttpRequestFactory extends SimpleClientHttpRequestFactory { // Keystore holding private keys (client certificate) private String keyStoreName; private String keyStorePassword; private String keyStoreType = "PKCS12"; // Keystore holding public certificate (server certificate) private String trustStoreName; private String trustStorePassword; private String trustStoreType = "PKCS12"; protected SSLSocketFactory socketFactory; protected HostnameVerifier hostnameVerifier; /** * */ public SSLSimpleClientHttpRequestFactory() { super(); } @PostConstruct protected void initialise() { // Builds the SSLSocketFactory if (keyStoreName != null && keyStorePassword != null && keyStoreType != null) { try { // Load KeyStore KeyStore keyStore = loadKeyStore(keyStoreName, keyStorePassword, keyStoreType); KeyManagerFactory keyMgrFactory = KeyManagerFactory.getInstance("SunX509"); keyMgrFactory.init(keyStore, keyStorePassword.toCharArray()); // Load TrustStore TrustManagerFactory trustMgrFactory = null; if (trustStoreName != null && trustStorePassword != null && trustStoreType != null) { KeyStore trustStore = loadKeyStore(trustStoreName, trustStorePassword, trustStoreType); trustMgrFactory = TrustManagerFactory.getInstance("SunX509"); trustMgrFactory.init(trustStore); } // create and initialize an SSLContext object SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(keyMgrFactory.getKeyManagers(), (trustMgrFactory != null ? trustMgrFactory.getTrustManagers() : null), null); // obtain the SSLSocketFactory from the SSLContext socketFactory = sslContext.getSocketFactory(); //SSLSocket theSocket = (SSLSocket) socketFactory.createSocket(host, port); } catch (GeneralSecurityException e) { throw new RuntimeException(e.getLocalizedMessage(), e); } } } protected KeyStore loadKeyStore(String storeName, String storePassword, String storeType) throws KeyStoreException, NoSuchAlgorithmException, CertificateException { KeyStore store = null; InputStream is = null; try { store = KeyStore.getInstance(storeType); try { is = new FileInputStream(storeName); } catch (FileNotFoundException fnfe) { if (Thread.currentThread().getContextClassLoader() != null) { is = Thread.currentThread().getContextClassLoader().getResourceAsStream(storeName); if (is == null) { throw fnfe; } } else { throw fnfe; } } store.load(is, storePassword.toCharArray()); } catch (IOException e) { throw new RuntimeException(e.getLocalizedMessage(), e); } finally { IOUtils.closeQuietly(is); } return store; } @Override protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException { super.prepareConnection(connection, httpMethod); // connection.addRequestProperty("Authorization", BASIC_AUTH + Base64.encode("user name" + ':' + "pass phrase")); if (connection instanceof HttpsURLConnection) { if (socketFactory != null) { ((HttpsURLConnection)connection).setSSLSocketFactory(socketFactory); } if (hostnameVerifier != null) { ((HttpsURLConnection)connection).setHostnameVerifier(hostnameVerifier); } } } /* * High-level accessors: KeyStore and TrustStore */ public void setKeyStoreName(String keyStoreName) { this.keyStoreName = keyStoreName; } public void setKeyStorePassword(String keyStorePassword) { this.keyStorePassword = keyStorePassword; } /** * @see KeyStore#getInstance(String) */ public void setKeyStoreType(String keyStoreType) { this.keyStoreType = keyStoreType; } public void setTrustStoreName(String trustStoreName) { this.trustStoreName = trustStoreName; } public void setTrustStorePassword(String trustStorePassword) { this.trustStorePassword = trustStorePassword; } /** * @see KeyStore#getInstance(String) */ public void setTrustStoreType(String trustStoreType) { this.trustStoreType = trustStoreType; } /* * Low-level accessors: SSLSocketFactory and HostnameVerifier */ public SSLSocketFactory getSocketFactory() { return socketFactory; } public void setSocketFactory(SSLSocketFactory socketFactory) { this.socketFactory = socketFactory; } public HostnameVerifier getHostnameVerifier() { return hostnameVerifier; } public void setHostnameVerifier(HostnameVerifier hostnameVerifier) { this.hostnameVerifier = hostnameVerifier; } }