如何为 Spring RestTemplate 设置要信任的证书

Posted

技术标签:

【中文标题】如何为 Spring RestTemplate 设置要信任的证书【英文标题】:How to set a certificate to be trusted for a spring RestTemplate 【发布时间】:2012-02-02 14:10:09 【问题描述】:

我在我的应用程序中使用 Spring RestTemplate 来访问外部 Web 服务。但是,此 Web 服务帽子 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>

我已将服务器证书导入密钥库,它肯定在其中。我还需要做什么?我已经在这里检查了所有类似的问题,但没有一个有帮助。谢谢。

【问题讨论】:

【参考方案1】:

您在 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 client certificates over HTTPS/SSL。

第三种方法是覆盖 https ProtocolSocketFactory 以便它接受所有证书,例如:http://drumcoder.co.uk/blog/2011/mar/30/httpclient-self-signed-certificates/

【讨论】:

所以在我的情况下,我应该将服务器证书导入 server-keystore.jks?或者它确实是可信证书的单独密钥库?还有一个问题,我应该导入服务器证书还是服务器 CA 证书?谢谢。【参考方案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());

简单。

【讨论】:

讨厌,永远不要相信每个人——在编程或现实生活中;-)

以上是关于如何为 Spring RestTemplate 设置要信任的证书的主要内容,如果未能解决你的问题,请参考以下文章

如何为 Rest 模板编写 Mockito Junit 测试用例?

在sql创建数据库表时,如何为字段设一个默认值

RestTemplate + OkHttp3 - gzip'ed响应的透明处理?

Spring Cloud Alibaba - 06 RestTemplate 实现自定义负载均衡算法

Spring @ContextConfiguration 如何为xml放置正确的位置

如何为 Spring Security 启用日志记录?