HttpClient s SSL
1. Prehľad
Tento článok ukáže, ako na to nakonfigurujte Apache HttpClient 4 s podporou protokolu SSL „Accept All“. Cieľ je jednoduchý - spotrebujte adresy HTTPS, ktoré nemajú platné certifikáty.
Ak sa chcete prehĺbiť a naučiť sa ďalšie super veci, ktoré môžete s HttpClient robiť - choďte ďalej hlavný sprievodca HttpClient.
2. The SSLPeerUnverifiedException
Bez konfigurácie SSL pomocou HttpClient, nasledujúci test - konzumácia adresy HTTPS - zlyhá:
verejná trieda RestClientLiveManualTest {@Test (očakáva sa = SSLPeerUnverifiedException.class) public void whenHttpsUrlIsConsumed_thenException () vyvolá ClientProtocolException, IOException {CloseableHttpClient httpClient = HttpClients.createDefault); Reťazec urlOverHttps = "// localhost: 8082 / httpclient-simple"; HttpGet getMethod = nový HttpGet (urlOverHttps); HttpResponse response = httpClient.execute (getMethod); assertThat (response.getStatusLine (). getStatusCode (), equalTo (200)); }}
Presné zlyhanie je:
javax.net.ssl.SSLPeerUnverifiedException: peer nie je autentifikovaný na sun.security.ssl.SSLSessionImpl.getPeerCertificates (SSLSessionImpl.java:397) na org.apache.http.conn.ssl.AbstractVerifier.verify (AbstractVerifier.java:126). ..
The javax.net.ssl.SSLPeerUnverifiedException výnimka nastane vždy, keď pre adresu URL nebolo možné vytvoriť platný reťazec dôvery.
3. Konfigurácia SSL - Prijať všetko (HttpClient <4.3)
Poďme teraz nakonfigurovať klienta HTTP tak, aby dôveroval všetkým reťazcom certifikátov bez ohľadu na ich platnosť:
@Test public final void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenOk () vyvolá GeneralSecurityException {HttpComponentsClientHttpRequestFactory requestFactory = nový HttpComponentsClientHttpRequestFactory (); CloseableHttpClient httpClient = (CloseableHttpClient) requestFactory.getHttpClient (); TrustStrategy accepttingTrustStrategy = (cert, authType) -> pravda; SSLSocketFactory sf = nový SSLSocketFactory (acceptTrustStrategy, ALLOW_ALL_HOSTNAME_VERIFIER); httpClient.getConnectionManager (). getSchemeRegistry (). register (nová schéma ("https", 8443, sf)); ResponseEntity response = nový RestTemplate (requestFactory). výmena (urlOverHttps, HttpMethod.GET, null, String.class); assertThat (response.getStatusCode (). value (), equalTo (200)); }
S novým TrustStrategy teraz má prednosť pred štandardným procesom overovania certifikátu (ktorý by sa mal obrátiť na nakonfigurovaného správcu dôvery) - test teraz vyhovuje a klient je schopný spotrebovať HTTPS URL.
4. Konfigurovať SSL - Prijať všetko (HttpClient 4.4 a vyššie)
S novým HTTPClientom teraz máme vylepšený a prepracovaný predvolený overovač názvu hostiteľa SSL. Aj so zavedením SSLConnectionSocketFactory a RegistryBuilder, je ľahké vybudovať SSLSocketFactory. Vyššie uvedený testovací prípad teda môžeme napísať ako:
@Test public final void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenOk () vyvolá GeneralSecurityException {TrustStrategy accepttingTrustStrategy = (cert, authType) -> true; SSLContext sslContext = SSLContexts.custom (). LoadTrustMaterial (null, receivingTrustStrategy) .build (); SSLConnectionSocketFactory sslsf = nový SSLConnectionSocketFactory (sslContext, NoopHostnameVerifier.INSTANCE); Registry socketFactoryRegistry = RegistryBuilder. create () .register ("https", sslsf) .register ("http", new PlainConnectionSocketFactory ()) .build (); BasicHttpClientConnectionManager connectionManager = nový BasicHttpClientConnectionManager (socketFactoryRegistry); CloseableHttpClient httpClient = HttpClients.custom (). SetSSLSocketFactory (sslsf) .setConnectionManager (connectionManager) .build (); HttpComponentsClientHttpRequestFactory requestFactory = nový HttpComponentsClientHttpRequestFactory (httpClient); ResponseEntity response = new RestTemplate (requestFactory) .exchange (urlOverHttps, HttpMethod.GET, null, String.class); assertThat (response.getStatusCode (). value (), equalTo (200)); }
5. Jar RestTemplate s SSL (HttpClient <4,3)
Teraz, keď sme videli, ako nakonfigurovať raw HttpClient s podporou SSL sa pozrime na klienta vyššej úrovne - jar RestTemplate.
Bez nakonfigurovaného protokolu SSL zlyhá nasledujúci test podľa očakávaní:
@Test (očakáva sa = ResourceAccessException.class) public void whenHttpsUrlIsConsumed_thenException () {String urlOverHttps = "// localhost: 8443 / httpclient-simple / api / bars / 1"; ResponseEntity response = new RestTemplate (). Exchange (urlOverHttps, HttpMethod.GET, null, String.class); assertThat (response.getStatusCode (). value (), equalTo (200)); }
Konfigurujme teda SSL:
@Test public void givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenException () vyvolá GeneralSecurityException {HttpComponentsClientHttpRequestFactory requestFactory = nový HttpComponentsClientHttpRequestFactory (); DefaultHttpClient httpClient = (DefaultHttpClient) requestFactory.getHttpClient (); TrustStrategy accepttingTrustStrategy = (cert, authType) -> true SSLSocketFactory sf = nový SSLSocketFactory (acceptTrustStrategy, ALLOW_ALL_HOSTNAME_VERIFIER); httpClient.getConnectionManager (). getSchemeRegistry () .register (nová schéma ("https", 8443, sf)); Reťazec urlOverHttps = "// localhost: 8443 / httpclient-simple / api / bars / 1"; ResponseEntity response = nový RestTemplate (requestFactory). výmena (urlOverHttps, HttpMethod.GET, null, String.class); assertThat (response.getStatusCode (). value (), equalTo (200)); }
Ako vidíte, je to tak veľmi podobné tomu, ako sme nakonfigurovali SSL pre surový HttpClient - nakonfigurujeme továreň na požiadavky s podporou SSL a potom vytvoríme inštanciu šablóny prechádzajúcej touto predkonfigurovanou továrňou.
6. Jar RestTemplate s SSL (HttpClient 4.4)
Rovnakým spôsobom môžeme nakonfigurovať aj naše RestTemplate:
@Test public void givenAcceptingAllCertificatesUsing4_4_whenUsingRestTemplate_thenCorrect () vyvolá ClientProtocolException, IOException {CloseableHttpClient httpClient = HttpClients.custom () .setSSLHostnameVerifier (nový NoopHostnameVerifier ()) HttpComponentsClientHttpRequestFactory requestFactory = nový HttpComponentsClientHttpRequestFactory (); requestFactory.setHttpClient (httpClient); ResponseEntity response = new RestTemplate (requestFactory) .exchange (urlOverHttps, HttpMethod.GET, null, String.class); assertThat (response.getStatusCode (). value (), equalTo (200)); }
7. Záver
V tomto výučbe sa diskutovalo o tom, ako nakonfigurovať SSL pre Apache HttpClient tak, aby bol schopný spotrebovať akúkoľvek adresu URL HTTPS bez ohľadu na certifikát. Rovnaká konfigurácia pre jar RestTemplate je tiež ilustrovaný.
Je však dôležité pochopiť, že táto stratégia úplne ignoruje kontrolu certifikátov - vďaka čomu je neistý a používa sa iba tam, kde to má zmysel.
Implementáciu týchto príkladov možno nájsť v projekte GitHub - jedná sa o projekt založený na Eclipse, takže by malo byť ľahké ho importovať a spustiť tak, ako je.