From f95a1fb3982395ccbc7e139cb5bd8a1c106bbb48 Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Wed, 11 Mar 2020 12:46:45 +0100 Subject: refactor HttpClientFactory.java to build HTTP clients with different authentication mechanisms --- .../eaaf/core/impl/utils/HttpClientFactory.java | 370 --------------------- 1 file changed, 370 deletions(-) delete mode 100644 eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpClientFactory.java (limited to 'eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpClientFactory.java') diff --git a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpClientFactory.java b/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpClientFactory.java deleted file mode 100644 index e681e705..00000000 --- a/eaaf_core_utils/src/main/java/at/gv/egiz/eaaf/core/impl/utils/HttpClientFactory.java +++ /dev/null @@ -1,370 +0,0 @@ -package at.gv.egiz.eaaf.core.impl.utils; - -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; - -import javax.annotation.PostConstruct; -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLContext; - -import at.gv.egiz.eaaf.core.api.idp.IConfiguration; -import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; -import at.gv.egiz.eaaf.core.exceptions.EaafException; -import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory; -import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration; -import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType; - -import org.apache.commons.lang3.StringUtils; -import org.apache.http.HttpRequest; -import org.apache.http.HttpResponse; -import org.apache.http.ProtocolException; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.CredentialsProvider; -import org.apache.http.client.RedirectStrategy; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpUriRequest; -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.LayeredConnectionSocketFactory; -import org.apache.http.conn.socket.PlainConnectionSocketFactory; -import org.apache.http.conn.ssl.NoopHostnameVerifier; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.impl.client.BasicCredentialsProvider; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.DefaultRedirectStrategy; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.apache.http.protocol.HttpContext; -import org.apache.http.ssl.SSLContexts; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.io.ResourceLoader; - -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class HttpClientFactory implements IHttpClientFactory { - - @Autowired(required = true) - private IConfiguration basicConfig; - - @Autowired(required = true) - ResourceLoader resourceLoader; - - @Autowired private EaafKeyStoreFactory keyStoreFactory; - - public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_USE = - "client.http.connection.pool.use"; - public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL = - "client.http.connection.pool.maxtotal"; - public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE = - "client.http.connection.pool.maxperroute"; - public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET = - "client.http.connection.timeout.socket"; - public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION = - "client.http.connection.timeout.connection"; - public static final String PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST = - "client.http.connection.timeout.request"; - public static final String PROP_CONFIG_CLIENT_HTTP_SSL_HOSTNAMEVERIFIER_TRUSTALL = - "client.http.ssl.hostnameverifier.trustall"; - - public static final String PROP_CONFIG_CLIENT_MODE = "client.authmode"; - public static final String PROP_CONFIG_CLIENT_AUTH_HTTP_USERNAME = "client.auth.http.username"; - public static final String PROP_CONFIG_CLIENT_AUTH_HTTP_PASSORD = "client.auth.http.password"; - public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PATH = - "client.auth.ssl.keystore.path"; - public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PASSORD = - "client.auth.ssl.keystore.password"; - private static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_NAME = - "client.auth.ssl.keystore.name"; - public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_TYPE = - "client.auth.ssl.keystore.type"; - public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEY_PASSWORD = - "client.auth.ssl.key.password"; - public static final String PROP_CONFIG_CLIENT_AUTH_SSL_KEY_ALIAS = "client.auth.ssl.key.alias"; - - // default configuration values - public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET = "15"; - public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION = "15"; - public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST = "30"; - public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL = "500"; - public static final String DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE = "100"; - - public enum ClientAuthMode { - NONE("none"), PASSWORD("password"), SSL("ssl"); - - private final String mode; - - ClientAuthMode(final String mode) { - this.mode = mode; - } - - /** - * Get the PVP mode. - * - * @return - */ - public String getMode() { - return this.mode; - } - - /** - * Get http-client authentication mode from String representation. - * - * @param s Config parameter - * @return - */ - public static ClientAuthMode fromString(final String s) { - try { - return ClientAuthMode.valueOf(s.toUpperCase()); - - } catch (IllegalArgumentException | NullPointerException e) { - return null; - } - } - - @Override - public String toString() { - return getMode(); - - } - - } - - private HttpClientBuilder httpClientBuilder = null; - - /* - * (non-Javadoc) - * - * @see at.gv.egiz.eaaf.core.impl.utils.IHttpClientFactory#getHttpClient() - */ - @Override - public CloseableHttpClient getHttpClient() { - return getHttpClient(true); - - } - - @Override - public CloseableHttpClient getHttpClient(final boolean followRedirects) { - RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); - if (!followRedirects) { - redirectStrategy = new RedirectStrategy() { - - @Override - public boolean isRedirected(final HttpRequest request, final HttpResponse response, - final HttpContext context) throws ProtocolException { - return false; - } - - @Override - public HttpUriRequest getRedirect(final HttpRequest request, final HttpResponse response, - final HttpContext context) throws ProtocolException { - return null; - } - }; - } - - return httpClientBuilder.setRedirectStrategy(redirectStrategy).build(); - - } - - @PostConstruct - private void initalize() { - // initialize http client - log.trace("Initializing HTTP Client-builder ... "); - httpClientBuilder = HttpClients.custom(); - - // set default request configuration - final RequestConfig requestConfig = - RequestConfig.custom() - .setConnectTimeout( - Integer.parseInt(basicConfig.getBasicConfiguration( - PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION, - DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_CONNECTION)) * 1000) - .setConnectionRequestTimeout(Integer.parseInt(basicConfig.getBasicConfiguration( - PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST, - DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_REQUEST)) * 1000) - .setSocketTimeout(Integer.parseInt( - basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET, - DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_TIMEOUT_SOCKET)) - * 1000) - .build(); - httpClientBuilder.setDefaultRequestConfig(requestConfig); - - ClientAuthMode clientAuthMode = ClientAuthMode.fromString( - basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_MODE, ClientAuthMode.NONE.getMode())); - if (clientAuthMode == null) { - log.warn("Can Not parse ClientAuthMode! Set mode to default value"); - clientAuthMode = ClientAuthMode.NONE; - - } - - // inject basic http authentication if required - log.info("Client authentication-mode is set to: {}", clientAuthMode); - injectBasicAuthenticationIfRequired(clientAuthMode); - - // inject authentication if required - final LayeredConnectionSocketFactory sslConnectionFactory = getSslContext(clientAuthMode); - - // set pool connection if required - injectConnectionPoolIfRequired(sslConnectionFactory); - - } - - private void injectBasicAuthenticationIfRequired(final ClientAuthMode clientAuthMode) { - if (clientAuthMode.equals(ClientAuthMode.PASSWORD)) { - final CredentialsProvider provider = new BasicCredentialsProvider(); - - final String username = - basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_HTTP_USERNAME); - final String password = - basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_HTTP_PASSORD); - - if (StringUtils.isEmpty(username)) { - log.warn("Http basic authentication was activated but NOT username was set!"); - - } - - log.trace("Injecting basic authentication with username: {} and password: {}", username, - password); - final UsernamePasswordCredentials credentials = - new UsernamePasswordCredentials(username, password); - provider.setCredentials(AuthScope.ANY, credentials); - httpClientBuilder.setDefaultCredentialsProvider(provider); - log.info("Basic http authentication was injected with username: {}", username); - - } else { - log.trace("Injection of Http Basic authentication was skipped"); - - } - - } - - private SSLContext buildSslContextWithSslClientAuthentication() - throws KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException, - KeyStoreException, EaafConfigurationException { - log.trace("Injecting SSL client-authentication into http client ... "); - final KeyStore keystore = getSslAuthKeyStore(); - final String keyPasswordString = - basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEY_PASSWORD); - log.trace("Open SSL Client-Auth keystore with password: {}", keyPasswordString); - final char[] keyPassword = keyPasswordString == null ? StringUtils.EMPTY.toCharArray() - : keyPasswordString.toCharArray(); - return SSLContexts.custom().loadKeyMaterial(keystore, keyPassword).build(); - - } - - private KeyStore getSslAuthKeyStore() throws EaafConfigurationException { - final String keyStoreType = basicConfig.getBasicConfiguration( - PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_TYPE, KeyStoreType.PKCS12.getKeyStoreType()); - final String localKeyStorePath = basicConfig - .getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PATH, StringUtils.EMPTY); - final String keyStorePassword = basicConfig - .getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_PASSORD, StringUtils.EMPTY); - final String keyStoreName = basicConfig - .getBasicConfiguration(PROP_CONFIG_CLIENT_AUTH_SSL_KEYSTORE_NAME, StringUtils.EMPTY); - - try { - final KeyStoreConfiguration keyStoreConfig = new KeyStoreConfiguration(); - keyStoreConfig.setKeyStoreType(keyStoreType); - keyStoreConfig.setFriendlyName("HttpClient Keystore"); - keyStoreConfig.setSoftKeyStoreFilePath(localKeyStorePath); - keyStoreConfig.setSoftKeyStorePassword(keyStorePassword); - keyStoreConfig.setKeyStoreName(keyStoreName); - - log.debug("Open keyStore with type: {}", keyStoreType); - final KeyStore keyStore = keyStoreFactory.buildNewKeyStore(keyStoreConfig).getFirst(); - - return keyStore; - - } catch (final EaafException e) { - log.warn("Can NOT read keyStore: {} from filesystem", localKeyStorePath, null, e); - throw new EaafConfigurationException("Can NOT read keyStore: {} from filesystem", - new Object[] { localKeyStorePath }, e); - - } - - } - - private LayeredConnectionSocketFactory getSslContext(final ClientAuthMode clientAuthMode) { - SSLContext sslContext = null; - try { - if (clientAuthMode.equals(ClientAuthMode.SSL)) { - sslContext = buildSslContextWithSslClientAuthentication(); - - } else { - log.trace("Initializing default SSL Context ... "); - sslContext = SSLContext.getDefault(); - - } - - // set hostname verifier - HostnameVerifier hostnameVerifier = null; - if (basicConfig.getBasicConfigurationBoolean( - PROP_CONFIG_CLIENT_HTTP_SSL_HOSTNAMEVERIFIER_TRUSTALL, false)) { - hostnameVerifier = new NoopHostnameVerifier(); - log.warn("HTTP client-builder deactivates SSL Host-name verification!"); - - } - - final LayeredConnectionSocketFactory sslSocketFactory = - new SSLConnectionSocketFactory(sslContext, hostnameVerifier); - - return sslSocketFactory; - - } catch (final NoSuchAlgorithmException | KeyManagementException | UnrecoverableKeyException - | KeyStoreException | EaafConfigurationException e) { - log.warn("HTTP client-builder can NOT initialze SSL-Context", e); - - } - - log.info("HTTP client-builder successfuly initialized"); - return null; - - } - - private void injectConnectionPoolIfRequired( - final LayeredConnectionSocketFactory sslConnectionFactory) { - if (basicConfig.getBasicConfigurationBoolean(PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_USE, - true)) { - PoolingHttpClientConnectionManager pool; - - // set socketFactoryRegistry if SSLConnectionFactory is Set - if (sslConnectionFactory != null) { - final Registry socketFactoryRegistry = - RegistryBuilder.create() - .register("http", PlainConnectionSocketFactory.getSocketFactory()) - .register("https", sslConnectionFactory).build(); - log.trace("Inject SSLSocketFactory into pooled connection"); - pool = new PoolingHttpClientConnectionManager(socketFactoryRegistry); - - } else { - pool = new PoolingHttpClientConnectionManager(); - - } - - pool.setDefaultMaxPerRoute(Integer.parseInt( - basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE, - DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXPERROUTE))); - pool.setMaxTotal(Integer.parseInt( - basicConfig.getBasicConfiguration(PROP_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL, - DEFAULT_CONFIG_CLIENT_HTTP_CONNECTION_POOL_MAXTOTAL))); - - httpClientBuilder.setConnectionManager(pool); - log.debug("Initalize http-client pool with, maxTotal: {} maxPerRoute: {}", pool.getMaxTotal(), - pool.getDefaultMaxPerRoute()); - - } else if (sslConnectionFactory != null) { - log.trace("Inject SSLSocketFactory without connection pool"); - httpClientBuilder.setSSLSocketFactory(sslConnectionFactory); - - } - - } - -} -- cgit v1.2.3