如何为Spring RestTemplate设置可信证书

6

我在应用程序中使用Spring RestTemplate来访问外部网络服务。这个网络服务启用了SSL,但是使用的是自签名证书(域名等也不合法)。这只是在本地网络上,所以我不必担心安全问题。我希望让Spring接受这个证书。我已经完成了以下步骤:

1.) 我已配置我的JBOSS 7使用这个密钥库。

<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.) 这是我的RestTemplate Bean配置(我在我的类中使用自动装配)

<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>

我已经将服务器证书导入密钥库,它肯定在里面。我还需要做什么?我已经检查过所有类似的问题,但都没有帮助。谢谢。
2个回答

2

您在jboss-web连接器中指定的server-keystore.jks仅用作传入连接的服务器证书。

对于传出连接,JBoss像任何其他Java客户端一样运行,因此您需要将服务器证书导入默认的Java信任库中。您可以使用默认的%JAVA_HOME%\lib\security\cacerts,并使用以下命令导入服务器证书:

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

如果您不想编辑默认的cacerts,可以通过设置系统属性来定义替代信任库,具体方法请参考:Java客户端证书和HTTPS/SSL
第三种方法是重写https ProtocolSocketFactory,使其接受所有证书,例如:httpclient自签名证书

那么在我的情况下,我应该将服务器证书导入到server-keystore.jks中吗?还是需要一个单独的密钥库用于受信任的证书?另外一个问题,我应该导入服务器证书还是服务器 CA 证书?谢谢。 - Filip Majernik

2
我建立了一个简单的方法:
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;
}

当我实例化 restTemplate 时:

 RestTemplate  restTemplate = new RestTemplate(getRequestFactory());

简单。

1
卑鄙,无论是在编程还是现实生活中都不要轻易相信每个人;-) - Jan Mares

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接