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/test/http/HttpClientFactoryTest.java | 328 +++++++++++++++++++++ 1 file changed, 328 insertions(+) create mode 100644 eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/http/HttpClientFactoryTest.java (limited to 'eaaf_core_utils/src/test') diff --git a/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/http/HttpClientFactoryTest.java b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/http/HttpClientFactoryTest.java new file mode 100644 index 00000000..b2f0f80e --- /dev/null +++ b/eaaf_core_utils/src/test/java/at/gv/egiz/eaaf/core/test/http/HttpClientFactoryTest.java @@ -0,0 +1,328 @@ +package at.gv.egiz.eaaf.core.test.http; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.Provider; +import java.security.cert.X509Certificate; + +import at.gv.egiz.eaaf.core.exceptions.EaafException; +import at.gv.egiz.eaaf.core.impl.credential.EaafKeyStoreFactory; +import at.gv.egiz.eaaf.core.impl.data.Pair; +import at.gv.egiz.eaaf.core.impl.http.HttpClientConfiguration; +import at.gv.egiz.eaaf.core.impl.http.IHttpClientFactory; + +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.impl.client.CloseableHttpClient; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import okhttp3.HttpUrl; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; +import okhttp3.tls.HandshakeCertificates; +import okhttp3.tls.HeldCertificate; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration("/spring/test_eaaf_pvp_not_lazy.beans.xml") +public class HttpClientFactoryTest { + + @Autowired private EaafKeyStoreFactory keyStoreFactory; + @Autowired private IHttpClientFactory httpClientFactory; + + private MockWebServer mockWebServer = null; + private HttpUrl mockServerUrl; + + /** + * JUnit test set-up. + * + */ + @Before + public void setup() { + + } + + /** + * jUnit test shutdown. + * + * @throws IOException In case of an mockWebServer error + */ + @After + public void shutdown() throws IOException { + if (mockWebServer != null) { + mockWebServer.shutdown(); + mockWebServer = null; + + } + + } + + @Test + public void getDefaultClient() { + final CloseableHttpClient client = httpClientFactory.getHttpClient(); + Assert.assertNotNull("httpClient", client); + + } + + @Test + public void getDefaultClientNoRedirect() { + final CloseableHttpClient client = httpClientFactory.getHttpClient(false); + Assert.assertNotNull("httpClient", client); + + } + + @Test + public void getCustomClientsDefault() throws EaafException { + final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); + Assert.assertFalse("Wrong default config - Hostnamevalidation", + config.isDisableHostnameValidation()); + Assert.assertFalse("Wrong default config - TLS Server-certs", + config.isDisableTlsHostCertificateValidation()); + + final CloseableHttpClient client1 = httpClientFactory.getHttpClient(config); + Assert.assertNotNull("first http client", client1); + + final CloseableHttpClient client2 = httpClientFactory.getHttpClient(config); + Assert.assertNotNull("second http client", client2); + + } + + @Test + public void getCustomClientUnknownAuthMethod() throws EaafException { + final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); + config.setAuthMode(RandomStringUtils.randomAlphabetic(5)); + final CloseableHttpClient client = httpClientFactory.getHttpClient(config); + Assert.assertNotNull("httpClient", client); + + } + + @Test + public void getCustomClientBasicAuth() throws EaafException, ClientProtocolException, IOException, InterruptedException { + final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); + config.setAuthMode("password"); + config.setUsername("jUnit"); + config.setPassword("password"); + + final CloseableHttpClient client = httpClientFactory.getHttpClient(config); + Assert.assertNotNull("httpClient", client); + + //setup test webserver that requestes http Basic authentication + mockWebServer = new MockWebServer(); + mockServerUrl = mockWebServer.url("/sp/junit"); + mockWebServer.enqueue(new MockResponse() + .setResponseCode(HttpURLConnection.HTTP_UNAUTHORIZED) + .addHeader("www-authenticate: Basic realm=\"protected area\"") + .setBody("Please authenticate.")); + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody("Successful auth!")); + + //request webservice + final HttpUriRequest httpGet2 = new HttpGet(mockServerUrl.url().toString()); + final CloseableHttpResponse httpResp2 = client.execute(httpGet2); + Assert.assertEquals("http statusCode", 200, httpResp2.getStatusLine().getStatusCode()); + + //check request contains basic authentication after authentication was requested + final RecordedRequest httpReq1 = mockWebServer.takeRequest(); + final RecordedRequest httpReq2 = mockWebServer.takeRequest(); + Assert.assertNull("wrong BasicAuthHeader", httpReq1.getHeader("Authorization")); + Assert.assertNotNull("missing BasicAuthHeader", httpReq2.getHeader("Authorization")); + + } + + @Test + public void getCustomClientBasicAuthNoUsername(){ + final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); + config.setAuthMode("password"); + try { + httpClientFactory.getHttpClient(config); + Assert.fail("Wrong config not detected"); + + } catch (final EaafException e) { + Assert.assertEquals("Wrong errorCode", "internal.httpclient.00", e.getErrorId()); + + } + } + + @Test + public void getCustomClientBasicAuthNoPassword() throws EaafException { + final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); + config.setAuthMode("password"); + config.setUsername(RandomStringUtils.randomAlphabetic(5)); + + final CloseableHttpClient client = httpClientFactory.getHttpClient(config); + Assert.assertNotNull("httpClient", client); + + } + + @Test + public void getCustomClientX509AuthNoKeyStoreConfig(){ + final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); + config.setAuthMode("ssl"); + try { + httpClientFactory.getHttpClient(config); + Assert.fail("Wrong config not detected"); + + } catch (final EaafException e) { + Assert.assertEquals("Wrong errorCode", "internal.httpclient.01", e.getErrorId()); + + } + } + + @Test + public void getCustomClientX509AuthNoKeyPassword() throws EaafException{ + final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); + config.setAuthMode("ssl"); + config.buildKeyStoreConfig( + "jks", + "src/test/resources/data/junit.jks", + "password", + null); + + try { + httpClientFactory.getHttpClient(config); + Assert.fail("Wrong config not detected"); + + } catch (final EaafException e) { + Assert.assertEquals("Wrong errorCode", "internal.httpclient.02", e.getErrorId()); + + } + } + + @Test + public void getCustomClientX509Auth() throws EaafException { + final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); + config.setAuthMode("ssl"); + config.buildKeyStoreConfig( + "jks", + "src/test/resources/data/junit.jks", + "password", + null); + config.setSslKeyPassword("password"); + + final CloseableHttpClient client = httpClientFactory.getHttpClient(config); + Assert.assertNotNull("httpClient", client); + + } + + @Test + public void getCustomClientX509AuthWithAlias() throws EaafException, ClientProtocolException, + IOException, KeyStoreException { + final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); + config.setAuthMode("ssl"); + config.buildKeyStoreConfig( + "jks", + "src/test/resources/data/junit.jks", + "password", + null); + config.setSslKeyPassword("password"); + config.setSslKeyAlias("sig"); + config.setDisableTlsHostCertificateValidation(true); + + final CloseableHttpClient client = httpClientFactory.getHttpClient(config); + Assert.assertNotNull("httpClient", client); + + //set-up mock-up web-server with SSL client authentication + final Pair sslClientKeyStore = + keyStoreFactory.buildNewKeyStore(config.getKeyStoreConfig()); + final String localhost = InetAddress.getByName("localhost").getCanonicalHostName(); + final HeldCertificate localhostCertificate = new HeldCertificate.Builder() + .addSubjectAlternativeName(localhost) + .build(); + final HandshakeCertificates serverCertificates = new HandshakeCertificates.Builder() + .addTrustedCertificate( + (X509Certificate) sslClientKeyStore.getFirst().getCertificate(config.getSslKeyAlias())) + .heldCertificate(localhostCertificate) + .build(); + mockWebServer = new MockWebServer(); + mockWebServer.useHttps(serverCertificates.sslSocketFactory(), false); + mockWebServer.requireClientAuth(); + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody("Successful auth!")); + mockServerUrl = mockWebServer.url("/sp/junit"); + + //perform test request + final HttpUriRequest httpGet2 = new HttpGet(mockServerUrl.url().toString()); + final CloseableHttpResponse httpResp2 = client.execute(httpGet2); + Assert.assertEquals("http statusCode", 200, httpResp2.getStatusLine().getStatusCode()); + + } + + @Test + public void getCustomClientX509AuthWrongKeyPassword() throws EaafException{ + final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); + config.setAuthMode("ssl"); + config.buildKeyStoreConfig( + "jks", + "src/test/resources/data/junit.jks", + "password", + null); + config.setSslKeyPassword(RandomStringUtils.randomAlphanumeric(5)); + config.setSslKeyAlias("sig"); + + try { + httpClientFactory.getHttpClient(config); + Assert.fail("Wrong key password not detected"); + + } catch (final EaafException e) { + Assert.assertEquals("Wrong errorCode", "internal.httpclient.03", e.getErrorId()); + + } + } + + @Test + public void getCustomClientX509AuthWithWrongAlias() throws EaafException, KeyStoreException, ClientProtocolException, IOException { + final HttpClientConfiguration config = new HttpClientConfiguration("jUnit"); + config.setAuthMode("ssl"); + config.buildKeyStoreConfig( + "jks", + "src/test/resources/data/junit.jks", + "password", + null); + config.setSslKeyPassword("password"); + config.setSslKeyAlias(RandomStringUtils.randomAlphabetic(5)); + config.setDisableHostnameValidation(true); + config.setFollowHttpRedirects(false); + config.setDisableTlsHostCertificateValidation(true); + + final CloseableHttpClient client = httpClientFactory.getHttpClient(config); + Assert.assertNotNull("httpClient", client); + + //set-up mock-up web-server with SSL client authentication + final Pair sslClientKeyStore = + keyStoreFactory.buildNewKeyStore(config.getKeyStoreConfig()); + final String localhost = InetAddress.getByName("localhost").getCanonicalHostName(); + final HeldCertificate localhostCertificate = new HeldCertificate.Builder() + .addSubjectAlternativeName(localhost) + .build(); + final HandshakeCertificates serverCertificates = new HandshakeCertificates.Builder() + .addTrustedCertificate( + (X509Certificate) sslClientKeyStore.getFirst().getCertificate("meta")) + .heldCertificate(localhostCertificate) + .build(); + mockWebServer = new MockWebServer(); + mockWebServer.useHttps(serverCertificates.sslSocketFactory(), false); + mockWebServer.requireClientAuth(); + mockWebServer.enqueue(new MockResponse().setResponseCode(200) + .setBody("Successful auth!")); + mockServerUrl = mockWebServer.url("/sp/junit"); + + //perform test request + final HttpUriRequest httpGet2 = new HttpGet(mockServerUrl.url().toString()); + final CloseableHttpResponse httpResp2 = client.execute(httpGet2); + Assert.assertEquals("http statusCode", 200, httpResp2.getStatusLine().getStatusCode()); + + } +} -- cgit v1.2.3