Java tutorial
/* * Copyright 2017 Marcus Portmann * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package guru.mmp.common.http; //~--- non-JDK imports -------------------------------------------------------- import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.*; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; //~--- JDK imports ------------------------------------------------------------ /** * The <code>SecureHttpClient</code> class implements a secure HTTP client builder. * * @author Marcus Portmann */ public class SecureHttpClientBuilder extends HttpClientBuilder { /* Logger */ @SuppressWarnings("unused") private static final Logger logger = LoggerFactory.getLogger(SecureHttpClientBuilder.class); private SSLConnectionSocketFactory sslSocketFactory; private boolean serverValidationEnabled = true; /** * Constructs a new <code>SecureHttpClientBuilder</code>. * * @param serverValidationEnabled should the connection to the remote server be validated */ public SecureHttpClientBuilder(boolean serverValidationEnabled) { this.serverValidationEnabled = serverValidationEnabled; SSLConnectionSocketFactory sslConnectionSocketFactory = getSSLConnectionSocketFactory(); Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() .register("https", sslConnectionSocketFactory).register("http", new PlainConnectionSocketFactory()) .build(); PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager( socketFactoryRegistry); setConnectionManager(connectionManager); } private synchronized SSLConnectionSocketFactory getSSLConnectionSocketFactory() { if (sslSocketFactory == null) { try { SSLContext sslContext = SSLContext.getInstance("TLS"); // Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { // Skip client verification step } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { if (serverValidationEnabled) { // TODO: Implement server certificate validation } } public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } } }; sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); sslSocketFactory = new SSLConnectionSocketFactory(sslContext.getSocketFactory(), new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession sslSession) { if (serverValidationEnabled) { // TODO: Implement proper verification of the server identity -- MARCUS } return true; // if (hostname.equalsIgnoreCase(sslSession.getPeerHost())) // { // return true; // } // else // { // logger.error("Failed to verify the SSL connection to the host (" // + hostname + ") which returned a certificate for the host (" + sslSession.getPeerHost() + ")"); // // return false; // } } }); } catch (Throwable e) { throw new RuntimeException("Failed to create the no-trust SSL socket factory", e); } } return sslSocketFactory; } }