HttpClient met SSL
1. Overzicht
Dit artikel laat zien hoe configureer de Apache HttpClient 4 met "Accept All" SSL-ondersteuning. Het doel is simpel: gebruik HTTPS-URL's die geen geldige certificaten hebben.
Als je dieper wilt graven en andere coole dingen wilt leren die je kunt doen met de HttpClient - ga dan naar de belangrijkste HttpClient-gids.
2. Het SSLPeerUnverifiedException
Zonder SSL te configureren met de HttpClient, zal de volgende test - waarbij een HTTPS-URL wordt gebruikt - mislukken:
openbare klasse RestClientLiveManualTest {@Test (verwacht = SSLPeerUnverifiedException.class) openbare leegte whenHttpsUrlIsConsumed_thenException () gooit ClientProtocolException, IOException {CloseableHttpClient httpClient = HttpClients.createDefault (); String urlOverHttps = "// localhost: 8082 / httpclient-simple"; HttpGet getMethod = nieuwe HttpGet (urlOverHttps); HttpResponse-antwoord = httpClient.execute (getMethod); assertThat (response.getStatusLine (). getStatusCode (), equalTo (200)); }}
De exacte fout is:
javax.net.ssl.SSLPeerUnverifiedException: peer niet geverifieerd op sun.security.ssl.SSLSessionImpl.getPeerCertificates (SSLSessionImpl.java:397) op org.apache.http.conn.ssl.AbstractVerifier.verify (AbstractVerifier.java:126). ..
De javax.net.ssl.SSLPeerUnverifiedException uitzondering treedt op wanneer er geen geldige vertrouwensketen voor de URL kan worden vastgesteld.
3. SSL configureren - Alles accepteren (HttpClient <4.3)
Laten we nu de HTTP-client configureren om alle certificaatketens te vertrouwen, ongeacht hun geldigheid:
@Test openbare laatste leegte gegevenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenOk () gooit GeneralSecurityException {HttpComponentsClientHttpRequestFactory requestFactory = nieuwe HttpComponentsClientHttpRequestFactory (); CloseableHttpClient httpClient = (CloseableHttpClient) requestFactory.getHttpClient (); Campsitetrategy acceptingTrustStrategy = (cert, authType) -> true; SSLSocketFactory sf = nieuwe SSLSocketFactory (accepteertTrustStrategy, ALLOW_ALL_HOSTNAME_VERIFIER); httpClient.getConnectionManager (). getSchemeRegistry (). register (nieuw schema ("https", 8443, sf)); ResponseEntity response = nieuwe RestTemplate (requestFactory). exchange (urlOverHttps, HttpMethod.GET, null, String.class); assertThat (response.getStatusCode (). value (), equalTo (200)); }
Met de nieuwe Setstrategy nu het standaard certificaatverificatieproces overschrijven (die een geconfigureerde trustmanager zou moeten raadplegen) - de test slaagt nu en de klant kan de HTTPS-URL gebruiken.
4. SSL configureren - Alles accepteren (HttpClient 4.4 en hoger)
Met de nieuwe HTTPClient hebben we nu een verbeterde, opnieuw ontworpen standaard SSL-hostnaamverificatie. Ook met de introductie van SSLConnectionSocketFactory en RegistryBuilder, is het eenvoudig om SSLSocketFactory te bouwen. Dus we kunnen de bovenstaande testcase schrijven als:
@Test openbare definitieve ongeldigheid gegevenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenOk () gooit GeneralSecurityException {urredtrategy acceptingTrustStrategy = (cert, authType) -> true; SSLContext sslContext = SSLContexts.custom (). LoadTrustMaterial (null, acceptingTrustStrategy) .build (); SSLConnectionSocketFactory sslsf = nieuwe SSLConnectionSocketFactory (sslContext, NoopHostnameVerifier.INSTANCE); Registry socketFactoryRegistry = RegistryBuilder. create () .register ("https", sslsf) .register ("http", nieuwe PlainConnectionSocketFactory ()) .build (); BasicHttpClientConnectionManager connectionManager = nieuwe BasicHttpClientConnectionManager (socketFactoryRegistry); CloseableHttpClient httpClient = HttpClients.custom (). SetSSLSocketFactory (sslsf) .setConnectionManager (connectionManager) .build (); HttpComponentsClientHttpRequestFactory requestFactory = nieuwe HttpComponentsClientHttpRequestFactory (httpClient); ResponseEntity response = nieuwe RestTemplate (requestFactory) .exchange (urlOverHttps, HttpMethod.GET, null, String.class); assertThat (response.getStatusCode (). value (), equalTo (200)); }
5. De lente RestTemplate met SSL (HttpClient <4.3)
Nu we hebben gezien hoe we een raw HttpClient met SSL-ondersteuning, laten we eens kijken naar een client op een hoger niveau - de lente RestTemplate.
Zonder SSL geconfigureerd, mislukt de volgende test zoals verwacht:
@Test (verwacht = ResourceAccessException.class) public void whenHttpsUrlIsConsumed_thenException () {String urlOverHttps = "// localhost: 8443 / httpclient-simple / api / bars / 1"; ResponseEntity response = nieuwe RestTemplate (). Exchange (urlOverHttps, HttpMethod.GET, null, String.class); assertThat (response.getStatusCode (). value (), equalTo (200)); }
Dus laten we SSL configureren:
@Test openbare ongeldige gegevenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenException () gooit GeneralSecurityException {HttpComponentsClientHttpRequestFactory requestFactory = nieuwe HttpComponentsClientHttpRequestFactory (); DefaultHttpClient httpClient = (DefaultHttpClient) requestFactory.getHttpClient (); Campsitetrategy acceptingTrustStrategy = (cert, authType) -> true SSLSocketFactory sf = nieuwe SSLSocketFactory (acceptingTrustStrategy, ALLOW_ALL_HOSTNAME_VERIFIER); httpClient.getConnectionManager (). getSchemeRegistry () .register (nieuw schema ("https", 8443, sf)); String urlOverHttps = "// localhost: 8443 / httpclient-simple / api / bars / 1"; ResponseEntity response = nieuwe RestTemplate (requestFactory). exchange (urlOverHttps, HttpMethod.GET, null, String.class); assertThat (response.getStatusCode (). value (), equalTo (200)); }
Zoals u kunt zien, is dit lijkt erg op de manier waarop we SSL hebben geconfigureerd voor de onbewerkte HttpClient - we configureren de aanvraagfabriek met SSL-ondersteuning en vervolgens instantiëren we de sjabloon die deze vooraf geconfigureerde fabriek passeert.
6. De lente RestTemplate met SSL (HttpClient 4.4)
En we kunnen op dezelfde manier onze RestTemplate:
@Test openbare ongeldige gegevenAcceptingAllCertificatesUsing4_4_whenUsingRestTemplate_thenCorrect () gooit ClientProtocolException, IOException {CloseableHttpClient httpClient = HttpClients.custom () .setSSLHostnameVerifier (nieuwe NoopHostname) .Verifier () HttpComponentsClientHttpRequestFactory requestFactory = nieuwe HttpComponentsClientHttpRequestFactory (); requestFactory.setHttpClient (httpClient); ResponseEntity response = nieuwe RestTemplate (requestFactory) .exchange (urlOverHttps, HttpMethod.GET, null, String.class); assertThat (response.getStatusCode (). value (), equalTo (200)); }
7. Conclusie
In deze tutorial werd besproken hoe SSL voor een Apache HttpClient moet worden geconfigureerd, zodat deze elke HTTPS-URL kan gebruiken, ongeacht het certificaat. Dezelfde configuratie voor de lente RestTemplate wordt ook geïllustreerd.
Een belangrijk ding om te begrijpen is echter dat deze strategie negeert certificaatcontrole volledig - waardoor het onveilig is en alleen te gebruiken waar dat zinvol is.
De implementatie van deze voorbeelden is te vinden in het GitHub-project - dit is een op Eclipse gebaseerd project, dus het moet gemakkelijk te importeren en uit te voeren zijn zoals het is.