package org.apereo.cas.config;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.ssl.SSLContexts;
import org.apereo.cas.authentication.FileTrustStoreSslSocketFactory;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.configuration.model.core.authentication.HttpClientProperties;
import org.apereo.cas.util.http.HttpClient;
import org.apereo.cas.util.http.SimpleHttpClient;
import org.apereo.cas.util.http.SimpleHttpClientFactoryBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import javax.net.ssl.HostnameVerifier;
/**
* This is {@link CasCoreHttpConfiguration}.
*
* @author Misagh Moayyed
* @since 5.1.0
*/
@Configuration("casCoreHttpConfiguration")
@EnableConfigurationProperties(CasConfigurationProperties.class)
@Order(value = Ordered.HIGHEST_PRECEDENCE)
@AutoConfigureBefore(CasCoreAuthenticationConfiguration.class)
public class CasCoreHttpConfiguration {
@Autowired
private CasConfigurationProperties casProperties;
@ConditionalOnMissingBean(name = "trustStoreSslSocketFactory")
@Bean
public SSLConnectionSocketFactory trustStoreSslSocketFactory() {
final HttpClientProperties.Truststore client = casProperties.getHttpClient().getTruststore();
if (client.getFile() != null && client.getFile().exists() && StringUtils.isNotBlank(client.getPsw())) {
return new FileTrustStoreSslSocketFactory(client.getFile(), client.getPsw());
}
return new SSLConnectionSocketFactory(SSLContexts.createSystemDefault());
}
@ConditionalOnMissingBean(name = "httpClient")
@Bean
public FactoryBean<SimpleHttpClient> httpClient() {
final SimpleHttpClientFactoryBean.DefaultHttpClient c = new SimpleHttpClientFactoryBean.DefaultHttpClient();
c.setConnectionTimeout(casProperties.getHttpClient().getConnectionTimeout());
c.setReadTimeout(Long.valueOf(casProperties.getHttpClient().getReadTimeout()).intValue());
return c;
}
@ConditionalOnMissingBean(name = "noRedirectHttpClient")
@Bean
public HttpClient noRedirectHttpClient() throws Exception {
return getHttpClient(false);
}
@ConditionalOnMissingBean(name = "supportsTrustStoreSslSocketFactoryHttpClient")
@Bean
public HttpClient supportsTrustStoreSslSocketFactoryHttpClient() throws Exception {
return getHttpClient(true);
}
@ConditionalOnMissingBean(name = "hostnameVerifier")
@Bean
public HostnameVerifier hostnameVerifier() {
if (casProperties.getHttpClient().getHostNameVerifier().equalsIgnoreCase("none")) {
return NoopHostnameVerifier.INSTANCE;
}
return new DefaultHostnameVerifier();
}
private HttpClient getHttpClient(final boolean redirectEnabled) throws Exception {
final SimpleHttpClientFactoryBean.DefaultHttpClient c = new SimpleHttpClientFactoryBean.DefaultHttpClient();
c.setConnectionTimeout(casProperties.getHttpClient().getConnectionTimeout());
c.setReadTimeout(Long.valueOf(casProperties.getHttpClient().getReadTimeout()).intValue());
c.setRedirectsEnabled(redirectEnabled);
c.setCircularRedirectsAllowed(redirectEnabled);
c.setSslSocketFactory(trustStoreSslSocketFactory());
c.setHostnameVerifier(hostnameVerifier());
return c.getObject();
}
}