客户端可以在没有证书的情况下使用 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 上的证书可恢复信任失败?