2012-01-04 36 views
6

Estoy usando Spring RestTemplate en mi aplicación para acceder a servicios web externos. Este servicio web con SSL habilitado, sin embargo, con un certificado autofirmado (dominio, etc.) tampoco es válido. Esto es solo en una red local, así que no tengo que preocuparme por algunos problemas de seguridad. Quiero hacer que Spring acepte este certificado. Esto es lo que he hecho hasta ahora:Cómo establecer un certificado de confianza para un resorte RestTemplate

1.) He configurado mi JBOSS 7 de usar este almacén de claves

<connector name="https" protocol="HTTP/1.1" socket-binding="https" scheme="https" enable-lookups="false" secure="true"> 
    <ssl name="ssl" key-alias="my-private-key" password="rmi+ssl" certificate-key-file="../standalone/configuration/server-keystore.jks" protocol="TLSv1" verify-client="false"/> 
</connector> 

2.) Aquí está la configuración de mi RestTemplate Bean (estoy usando autowireing en mis clases)

<bean id="stringHttpConverter" class="org.springframework.http.converter.StringHttpMessageConverter"></bean> 

<bean id="httpClientParams" class="org.apache.commons.httpclient.params.HttpClientParams"> 
    <property name="authenticationPreemptive" value="true"/> 
    <property name="connectionManagerClass" value="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager"/> 
</bean> 

<bean id="httpClient" class="org.apache.commons.httpclient.HttpClient"> 
    <constructor-arg ref="httpClientParams"/> 
</bean> 

<bean id="httpClientFactory" class="org.springframework.http.client.CommonsClientHttpRequestFactory"> 
    <constructor-arg ref="httpClient"/> 
</bean> 

<bean id="restTemplate" class="org.springframework.web.client.RestTemplate"> 
    <constructor-arg ref="httpClientFactory"/> 
    <property name="messageConverters"> 
     <list> 
      <!-- <ref bean="marshallingConverter" /> --> 
      <ref bean="stringHttpConverter" />    
     </list> 
    </property> 
</bean> 

he importado el certificado de servidor en el almacén de claves, es definitivamente allí. ¿Qué más tengo que hacer? Ya he consultado todas las preguntas similares aquí, pero ninguna de ellas me ayudó. Gracias.

Respuesta

2

El servidor-keystore.jks que ha especificado en el conector para jboss-web solo se utiliza como certificado de servidor para las conexiones entrantes.

Para las conexiones de salida, JBoss actúa como cualquier otro cliente de Java, por lo que debe importar el certificado del servidor al almacén de confianza de java predeterminado. Se podría utilizar el% JAVA_HOME% \ lib \ security default \ cacerts, e importar el certificado de servidor usando:

keytool -import -trustcacerts -keystore cacerts -storepass changeit -noprompt -alias mycert -file mycert.cer 

Si no desea editar los cacerts defecto, se podría definir un almacén de confianza alternativa por el sistema de ajuste de propiedades como se explica en: Java client certificates over HTTPS/SSL.

Una tercera forma es para anular el https ProtocolSocketFactory para que acepte todos los certificados, como: http://drumcoder.co.uk/blog/2011/mar/30/httpclient-self-signed-certificates/

+0

Entonces, ¿en mi caso debería importar el certificado del servidor en server-keystore.jks? ¿O se trata de un almacén de claves separado para certificados de confianza? Y otra pregunta, ¿debería importar el certificado del servidor o el certificado CA del servidor? Gracias. –

0

Hice un método simple:

static HttpComponentsClientHttpRequestFactory requestFactory = null; 

/** 
* 
* @return 
*/ 
public static ServerProperties getServerProperties() { 
    return serverProperties; 
} 

/** 
* @return 
*/ 
public static HttpComponentsClientHttpRequestFactory getRequestFactory() { 
    if (requestFactory == null) { 
     TrustStrategy acceptingTrustStrategy = new TrustStrategy() { 
      @Override 
      public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { 
       return true; 
      } 
     }; 
     SSLContext sslContext = null; 
     try { 
      sslContext = org.apache.http.ssl.SSLContexts.custom() 
        .loadTrustMaterial(null, acceptingTrustStrategy) 
        .build(); 
      SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext); 

      CloseableHttpClient httpClient = HttpClients.custom() 
        .setSSLSocketFactory(csf) 
        .build(); 
      requestFactory = new HttpComponentsClientHttpRequestFactory(); 
      requestFactory.setHttpClient(httpClient); 
     } catch (NoSuchAlgorithmException e) { 
      e.printStackTrace(); 
     } catch (KeyManagementException e) { 
      e.printStackTrace(); 
     } catch (KeyStoreException e) { 
      e.printStackTrace(); 
     } 
    } 
    return requestFactory; 
} 

Luego, cuando me restTemplate ejemplo:

RestTemplate restTemplate = new RestTemplate(getRequestFactory()); 

Simple.

Cuestiones relacionadas