客户端可以在没有证书的情况下使用 RestTemplate 向安全 SSL 服务器发出请求吗?

Posted

技术标签:

【中文标题】客户端可以在没有证书的情况下使用 RestTemplate 向安全 SSL 服务器发出请求吗?【英文标题】:Can a client make a request with RestTemplate without a certificate to a secure SSL server? 【发布时间】:2020-10-12 17:57:40 【问题描述】:

有人可以帮我解决以下问题吗:

我有一个启用了 SSL 的 REST 服务器和一个位于 2 台不同计算机上的 REST 客户端。两者都是用 Spring Boot 构建的。服务器将具有 .p12 或 .pfx 证书。

如果 REST 客户端想要向服务器发出请求,它是否需要提供证书,或者即使服务器是安全的,它也可以使用简单的 RestTemplate 发出请求?相同的规则是否适用于 Postman,或者 Postman 也可以在没有证书的情况下发送请求?

我尝试使用带有证书的 REST 模板从 REST 客户端创建请求。但我不确定,我应该提供哪个证书。它应该是服务器上的相同证书还是另一个证书?并且来自服务器的证书是否需要对 REST 客户端的 ip 有一个规则以允许请求?

ssl服务器配置:

ssl:
 key-store-type: PKCS12
 key-store: $MY_DIR/config/ssl/myCert.pfx
 key-store-password: 123456

来自客户端的其余模板:

 RestTemplate restTemplate = null;
    try 
        SSLContext sslContext = SSLContextBuilder
            .create()
            .loadTrustMaterial(ResourceUtils.getFile("classpath:config/ssl/myCert.pfx"), password.toCharArray())
            .build();

        HttpClient client = HttpClients.custom()
            .setSSLContext(sslContext)
            .build();

        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setHttpClient(client);

        restTemplate = new RestTemplate(requestFactory);
     catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | KeyManagementException ex) 
        LOGGER.error("Error getting the RestTemplate with ssl certificate", ex);
    

【问题讨论】:

【参考方案1】:

是否需要客户端证书完全取决于服务器配置。有些服务器需要客户端证书,有些则不需要。请参阅您的特定 REST API 的文档以了解客户端的要求。

【讨论】:

【参考方案2】:
@Bean
public RestTemplate restTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException 
        TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
        SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();

        SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
        CloseableHttpClient httpClient = HttpClients.custom()
                        .setSSLSocketFactory(csf)
                        .build();

        HttpComponentsClientHttpRequestFactory requestFactory =
                        new HttpComponentsClientHttpRequestFactory();
        requestFactory.setHttpClient(httpClient);
        RestTemplate restTemplate = new RestTemplate(requestFactory);
    return restTemplate;

这对我有用。

【讨论】:

【参考方案3】:

请使用下面的导入包。

import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
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.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.ssl.TrustStrategy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

【讨论】:

以上是关于客户端可以在没有证书的情况下使用 RestTemplate 向安全 SSL 服务器发出请求吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不强制断开连接的情况下使用 Go TLS 手动验证客户端证书?

使用 apache httpClient 客户端在没有 ssl 证书验证的情况下将发布数据发送到 https

如何在没有 SecTrustGetTrustResult 的情况下诊断 iOS 上的证书可恢复信任失​​败?

我可以在没有代码签名 EKU 的情况下使用证书签署自解压 exe 吗?

python MySQLdb:在没有证书的情况下使用ssl

苹果证书,有啥方法可以在没有代理的情况下提交给 iTunes?