example spring validation ssl-certificate resttemplate

example - Deshabilitar la validación del certificado SSL en Spring RestTemplate



spring rest ssl example (5)

Tengo dos aplicaciones web basadas en Spring A y B, en dos máquinas diferentes.

Deseo hacer una llamada https desde la aplicación web A a la aplicación web B, sin embargo, estoy usando un certificado autofirmado en la Máquina B. Por lo tanto, mi solicitud HTTPS falla.

¿Cómo puedo desactivar la validación del certificado https cuando uso RestTemplate en Spring? Deseo desactivar la validación porque ambas aplicaciones web A y B están dentro de la red interna, pero la transferencia de datos tiene que ocurrir a través de HTTPS


Básicamente, dos cosas que debe hacer es usar una estrategia de TrustS personalizada que confíe en todos los certs , y también use NoopHostnameVerifier () para deshabilitar la verificación del nombre de host. Aquí está el código, con todas las importaciones relevantes:

import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.SSLContext; import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; public RestTemplate getRestTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException { TrustStrategy acceptingTrustStrategy = new TrustStrategy() { @Override public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { return true; } }; SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build(); SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier()); CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build(); HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); requestFactory.setHttpClient(httpClient); RestTemplate restTemplate = new RestTemplate(requestFactory); return restTemplate; }


Puedes usar esto con HTTPClient API.

public RestTemplate getRestTemplateBypassingHostNameVerifcation() { CloseableHttpClient httpClient = HttpClients.custom().setSSLHostnameVerifier(new NoopHostnameVerifier()).build(); HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); requestFactory.setHttpClient(httpClient); return new RestTemplate(requestFactory); }


Lo que necesita agregar es una clase HostnameVerifier personalizada que omite la verificación del certificado y devuelve true

HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } });

Esto debe ser colocado apropiadamente en su código.


@Bean public RestTemplate restTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException { TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true; SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom() .loadTrustMaterial(null, acceptingTrustStrategy) .build(); SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext); CloseableHttpClient httpClient = HttpClients.custom() .setSSLSocketFactory(csf) .build(); HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); requestFactory.setHttpClient(httpClient); RestTemplate restTemplate = new RestTemplate(requestFactory); return restTemplate; }


Add my response with cookie : public static void main(String[] args) { MultiValueMap<String, String> params = new LinkedMultiValueMap<>(); params.add("username", testUser); params.add("password", testPass); NullHostnameVerifier verifier = new NullHostnameVerifier(); MySimpleClientHttpRequestFactory requestFactory = new MySimpleClientHttpRequestFactory(verifier , rememberMeCookie); ResponseEntity<String> response = restTemplate.postForEntity(appUrl + "/login", params, String.class); HttpHeaders headers = response.getHeaders(); String cookieResponse = headers.getFirst("Set-Cookie"); String[] cookieParts = cookieResponse.split(";"); rememberMeCookie = cookieParts[0]; cookie.setCookie(rememberMeCookie); requestFactory = new MySimpleClientHttpRequestFactory(verifier,cookie.getCookie()); restTemplate.setRequestFactory(requestFactory); } public class MySimpleClientHttpRequestFactory extends SimpleClientHttpRequestFactory { private final HostnameVerifier verifier; private final String cookie; public MySimpleClientHttpRequestFactory(HostnameVerifier verifier ,String cookie) { this.verifier = verifier; this.cookie = cookie; } @Override protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException { if (connection instanceof HttpsURLConnection) { ((HttpsURLConnection) connection).setHostnameVerifier(verifier); ((HttpsURLConnection) connection).setSSLSocketFactory(trustSelfSignedSSL().getSocketFactory()); ((HttpsURLConnection) connection).setAllowUserInteraction(true); String rememberMeCookie = cookie == null ? "" : cookie; ((HttpsURLConnection) connection).setRequestProperty("Cookie", rememberMeCookie); } super.prepareConnection(connection, httpMethod); } public SSLContext trustSelfSignedSSL() { try { SSLContext ctx = SSLContext.getInstance("TLS"); X509TrustManager tm = new X509TrustManager() { public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { } public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { } public X509Certificate[] getAcceptedIssuers() { return null; } }; ctx.init(null, new TrustManager[] { tm }, null); SSLContext.setDefault(ctx); return ctx; } catch (Exception ex) { ex.printStackTrace(); } return null; } } public class NullHostnameVerifier implements HostnameVerifier { public boolean verify(String hostname, SSLSession session) { return true; } }