HttpClient עם SSL

1. סקירה כללית

מאמר זה יראה כיצד הגדר את ה- Apache HttpClient 4 עם תמיכה ב- SSL "קבל הכל". המטרה היא פשוטה - צרכו כתובות אתרי HTTPS שאין להן אישורים תקפים.

אם אתה רוצה להתעמק וללמוד דברים מגניבים אחרים אתה יכול לעשות עם ה- HttpClient - המשך אל המדריך הראשי של HttpClient.

2. ה SSLPeerUnverifiedException

בלי להגדיר SSL עם ה- HttpClient, הבדיקה הבאה - צריכת URL של HTTPS - תיכשל:

מחלקה ציבורית RestClientLiveManualTest {@Test (צפוי = SSLPeerUnverifiedException.class) בטל ציבורי כאשר HttpsUrlIsConsumed_thenException () זורק ClientProtocolException, IOException {CloseableHttpClient httpClient = HttpClients.createDefault; מחרוזת urlOverHttps = "// localhost: 8082 / httpclient-simple"; HttpGet getMethod = HttpGet חדש (urlOverHttps); תגובה HttpResponse = httpClient.execute (getMethod); assertThat (response.getStatusLine (). getStatusCode (), equalTo (200)); }}

הכישלון המדויק הוא:

javax.net.ssl.SSLPeerUnverifiedException: עמית לא מאומת ב- sun.security.ssl.SSLSessionImpl.getPeerCertificates (SSLSessionImpl.java:397) ב- org.apache.http.conn.ssl.AbstractVerifier.verify (AbstractVerifier.java12. ..

ה javax.net.ssl.SSLPeerUnverifiedException יוצא מן הכלל מתרחש בכל פעם שלא ניתן היה ליצור שרשרת אמון חוקית עבור כתובת האתר.

3. הגדר את התצורה של SSL - קבל הכל (HttpClient <4.3)

בואו כעת נגדיר את לקוח ה- HTTP לסמוך על כל שרשראות האישורים ללא קשר לתוקפו:

@Test הסופי הציבורי בטל givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenOk () זורק GeneralSecurityException {HttpComponentsClientHttpRequestFactory requestFactory = חדש HttpComponentsClientHttpRequestFactory (); CloseableHttpClient httpClient = (CloseableHttpClient) requestFactory.getHttpClient (); TrustStrategy acceptingTrustStrategy = (cert, authType) -> true; SSLSocketFactory sf = SSLSocketFactory חדש (acceptTrustStrategy, ALLOW_ALL_HOSTNAME_VERIFIER); httpClient.getConnectionManager (). getSchemeRegistry (). הרשמה (תוכנית חדשה ("https", 8443, sf)); תגובה ResponseEntity = RestTemplate חדש (requestFactory). exchange (urlOverHttps, HttpMethod.GET, null, String.class); assertThat (response.getStatusCode (). value (), equalTo (200)); }

עם החדש TrustStrategy עַכשָׁיו עוקף את תהליך אימות האישורים הסטנדרטי (שאמור להתייעץ עם מנהל אמון מוגדר) - הבדיקה עוברת כעת ו הלקוח מסוגל לצרוך את כתובת ה- HTTPS.

4. הגדר את התצורה של SSL - קבל הכל (HttpClient 4.4 ומעלה)

עם HTTPClient החדש, כעת יש לנו מאמת ברירת מחדל משופר ומעוצב מחדש של ברירת מחדל SSL. גם עם הצגתו של SSLConnectionSocketFactory ו RegistryBuilder, קל לבנות SSLSocketFactory. כדי שנוכל לכתוב את מקרה הבדיקה שלעיל כמו:

@Test הסופי הציבורי בטל givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenOk () זורק GeneralSecurityException {TrustStrategy acceptingTrustStrategy = (cert, authType) -> true; SSLContext sslContext = SSLContexts.custom (). LoadTrustMaterial (null, acceptingTrustStrategy) .build (); SSLConnectionSocketFactory sslsf = SSLConnectionSocketFactory חדש (sslContext, NoopHostnameVerifier.INSTANCE); רישום socketFactoryRegistry = RegistryBuilder. צור () .register ("https", sslsf) .register ("http", PlainConnectionSocketFactory חדש ()) .build (); BasicHttpClientConnectionManager connectionManager = BasicHttpClientConnectionManager חדש (socketFactoryRegistry); CloseableHttpClient httpClient = HttpClients.custom (). SetSSLSocketFactory (sslsf) .setConnectionManager (connectionManager) .build (); HttpComponentsClientHttpRequestFactory requestFactory = חדש HttpComponentsClientHttpRequestFactory (httpClient); ResponseEntity response = RestTemplate חדש (requestFactory). Exchange (urlOverHttps, HttpMethod.GET, null, String.class); assertThat (response.getStatusCode (). value (), equalTo (200)); }

5. האביב RestTemplate עם SSL (HttpClient <4.3)

עכשיו כשראינו כיצד להגדיר Raw HttpClient עם תמיכה ב- SSL, בואו נסתכל על לקוח ברמה גבוהה יותר - האביב RestTemplate.

ללא הגדרת SSL, הבדיקה הבאה נכשלת כצפוי:

@Test (צפוי = ResourceAccessException.class) בטל בציבור כאשרHttpsUrlIsConsumed_thenException () {String urlOverHttps = "// localhost: 8443 / httpclient-simple / api / bars / 1"; תגובה ResponseEntity = RestTemplate חדש (). Exchange (urlOverHttps, HttpMethod.GET, null, String.class); assertThat (response.getStatusCode (). value (), equalTo (200)); }

אז בואו נגדיר SSL:

@Test הציבור בטל givenAcceptingAllCertificates_whenHttpsUrlIsConsumed_thenException () זורק GeneralSecurityException {HttpComponentsClientHttpRequestFactory requestFactory = HttpComponentsClientHttpRequestFactory () חדש; DefaultHttpClient httpClient = (DefaultHttpClient) requestFactory.getHttpClient (); TrustStrategy acceptingTrustStrategy = (cert, authType) -> נכון SSLSocketFactory sf = SSLSocketFactory חדש (acceptTrustStrategy, ALLOW_ALL_HOSTNAME_VERIFIER); httpClient.getConnectionManager (). getSchemeRegistry () .register (תוכנית חדשה ("https", 8443, sf)); מחרוזת urlOverHttps = "// localhost: 8443 / httpclient-simple / api / bars / 1"; תגובה ResponseEntity = RestTemplate חדש (requestFactory). exchange (urlOverHttps, HttpMethod.GET, null, String.class); assertThat (response.getStatusCode (). value (), equalTo (200)); }

כפי שאתה יכול לראות, זהו דומה מאוד לאופן שבו הגדרנו SSL עבור HttpClient הגולמי - אנו מגדירים את מפעל הבקשה עם תמיכה ב- SSL ואז אנו מיישרים את התבנית העוברת את המפעל שהוגדר מראש.

6. האביב RestTemplate עם SSL (HttpClient 4.4)

ונוכל להשתמש באותה דרך להגדרת התצורה שלנו RestTemplate:

@Test ציבורי בטל givenAcceptingAllCertificatesUsing4_4_whenUsingRestTemplate_thenCorrect () זורק ClientProtocolException, IOException {CloseableHttpClient httpClient = HttpClients.custom () .setSSLHostnameVerifier (NoopHost;). HttpComponentsClientHttpRequestFactory requestFactory = חדש HttpComponentsClientHttpRequestFactory (); requestFactory.setHttpClient (httpClient); ResponseEntity response = RestTemplate חדש (requestFactory). Exchange (urlOverHttps, HttpMethod.GET, null, String.class); assertThat (response.getStatusCode (). value (), equalTo (200)); }

7. מסקנה

הדרכה זו דנה כיצד להגדיר SSL עבור HttpClient של אפאצ'י כך שהוא יוכל לצרוך כל כתובת אתר של HTTPS, ללא קשר לאישור. אותה תצורה עבור האביב RestTemplate מאויר גם.

דבר חשוב להבין עם זאת הוא אסטרטגיה זו מתעלמת לחלוטין מבדיקת האישורים - מה שהופך אותו לחסר ביטחון ורק להשתמש בו היכן שזה הגיוני.

יישום הדוגמאות הללו ניתן למצוא בפרויקט GitHub - זהו פרויקט מבוסס Eclipse, כך שיהיה קל לייבא ולהפעיל אותו כפי שהוא.


$config[zx-auto] not found$config[zx-overlay] not found