2010-11-01 46 views
28

Tengo dos aplicaciones web basadas en Spring A y B en dos máquinas diferentes.Desactivación de la validación del certificado SSL en Spring RestTemplate

Quiero 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? Quiero desactivar la validación porque ambos aplicación web A y B se encuentran dentro de la red interna, pero la transferencia de datos tiene que pasar a través de HTTPS

Respuesta

26

Lo que hay que añadir es una costumbre HostnameVerifier clase no pasa la verificación del certificado y devuelve verdadero

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

Esto debe colocarse adecuadamente en su código.

+0

Estoy usando la clase Spring's RestTemplate, ¿sabes cómo puedo hacer eso en RestTemplate? – Ram

+6

En realidad esto está fuera de RestTemplate. Algunos ejemplos de código están disponibles en http://forum.springsource.org/showthread.php?t=60854. También vea http://stackoverflow.com/questions/1725863/ssl-handshake-issue-using-spring-resttemplate – Raghuram

+0

Vio esos enlaces y lo puso a funcionar. Gracias :) – Ram

6
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; 
      } 
     } 
+0

NullHostnameVerifier verifier = new NullHostnameVerifier(); usted puede ver me recuerda cookie es un String –

19
@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; 
} 
+0

encanto .......... – Valath

9

esencialmente dos cosas que hay que hacer son utilizar un TrustStrategy personalizado que confía en todos los CERT, y también utilizar NoopHostnameVerifier() para desactivar la verificación 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; 
} 
+1

gracias, esto funcionó para mí! – Humoyun

+1

TrustStrategy aceptarTrustStrategy = (X509Certificate [] x509Certificates, String s) -> true; – Humoyun

+1

Gracias, esto me salvó la vida. Todos los otros métodos (agregando .crt exportado a jace cacerts usando keytool, http://blog.codeleak.pl/2016/02/skip-ssl-certificate-verification-in.html, y alrededor de 5 ~ 6 otras publicaciones de stackoverflow incluyendo respuestas en este caso) falló, tomó 7 horas de mi tiempo. Esta respuesta fue mi última esperanza, gracias. –

0

Puedes utilizar 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); 

} 
Cuestiones relacionadas