[英]How to disable SSL certificate checking with Spring RestTemplate?
I am trying to write an integration test where our test launches an embedded HTTPS server using Simple .我正在尝试编写一个集成测试,我们的测试使用Simple启动嵌入式 HTTPS 服务器。 I created a self-signed certificate using
keytool
and am able to access the server using a browser (specifically Chrome, and I do get a warning about the self-signed certificate).我使用
keytool
创建了一个自签名证书,并且能够使用浏览器访问服务器(特别是 Chrome,我确实收到了关于自签名证书的警告)。
However, when I try to connect using Spring RestTemplate , I get a ResourceAccessException :但是,当我尝试使用Spring RestTemplate进行连接时,我得到了ResourceAccessException :
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "https://localhost:8088":sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; nested exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:557)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:502)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:444)
at net.initech.DummySslServer.shouldConnect(DummySslServer.java:119)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1917)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:301)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:295)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1369)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:156)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:925)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:860)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1043)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1343)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1371)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1355)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:153)
at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:78)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:52)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:541)
... 33 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
at sun.security.validator.Validator.validate(Validator.java:260)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1351)
... 47 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:145)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:131)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
... 53 more
From other questions and blog posts I've seen the advice to replace the HostnameVerifier
with something like从其他问题和博客文章中,我看到了用类似的东西替换
HostnameVerifier
的建议
private static final HostnameVerifier PROMISCUOUS_VERIFIER = ( s, sslSession ) -> true;
And I've set it both globally and on the RestTemplate
itself:我已经在全局和
RestTemplate
本身上设置了它:
HttpsURLConnection.setDefaultHostnameVerifier( PROMISCUOUS_VERIFIER );
...and on the RestTemplate
itself: ...以及
RestTemplate
本身:
final RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory( new SimpleClientHttpRequestFactory() {
@Override
protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
if(connection instanceof HttpsURLConnection ){
((HttpsURLConnection) connection).setHostnameVerifier(PROMISCUOUS_VERIFIER);
}
super.prepareConnection(connection, httpMethod);
}
});
Yet, I am still getting the above error.然而,我仍然收到上述错误。 How can I get around it?
我怎样才能绕过它?
RestTemplate
and that we are configuring it correctly.RestTemplate
之上的库并且我们正在正确配置它。 I am using Java 8 (but could use 7) and Spring 4.0.3.我正在使用 Java 8(但可以使用 7)和 Spring 4.0.3。
I wish I still had a link to the source that lead me in this direction, but this is the code that ended up working for me.我希望我仍然有一个指向这个方向的源代码的链接,但这是最终为我工作的代码。 By looking over the JavaDoc for X509TrustManager it looks like the way the
TrustManager
s work is by returning nothing on successful validation, otherwise throwing an exception.通过查看X509TrustManager的 JavaDoc,看起来
TrustManager
的工作方式是在成功验证时不返回任何内容,否则抛出异常。 Thus, with a null implementation , it is treated as a successful validation.因此,对于null implementation ,它被视为成功的验证。 Then you remove all other implementations.
然后删除所有其他实现。
import javax.net.ssl.*;
import java.security.*;
import java.security.cert.X509Certificate;
public final class SSLUtil{
private static final TrustManager[] UNQUESTIONING_TRUST_MANAGER = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers(){
return null;
}
public void checkClientTrusted( X509Certificate[] certs, String authType ){}
public void checkServerTrusted( X509Certificate[] certs, String authType ){}
}
};
public static void turnOffSslChecking() throws NoSuchAlgorithmException, KeyManagementException {
// Install the all-trusting trust manager
final SSLContext sc = SSLContext.getInstance("SSL");
sc.init( null, UNQUESTIONING_TRUST_MANAGER, null );
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
public static void turnOnSslChecking() throws KeyManagementException, NoSuchAlgorithmException {
// Return it to the initial state (discovered by reflection, now hardcoded)
SSLContext.getInstance("SSL").init( null, null, null );
}
private SSLUtil(){
throw new UnsupportedOperationException( "Do not instantiate libraries.");
}
}
For the sake of other developers who finds this question and need another solution that fits not only for unit-tests:为了找到这个问题并需要另一个不仅适合单元测试的解决方案的其他开发人员:
I've found this on a blog (not my solution! Credit to the blog's owner).我在博客上找到了这个(不是我的解决方案!感谢博客所有者)。
TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()
.loadTrustMaterial(null, acceptingTrustStrategy)
.build();
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(csf)
.build();
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
RestTemplate restTemplate = new RestTemplate(requestFactory);
You can also register your keystore :您还可以注册您的密钥库:
private void registerKeyStore(String keyStoreName) {
try {
ClassLoader classLoader = this.getClass().getClassLoader();
InputStream keyStoreInputStream = classLoader.getResourceAsStream(keyStoreName);
if (keyStoreInputStream == null) {
throw new FileNotFoundException("Could not find file named '" + keyStoreName + "' in the CLASSPATH");
}
//load the keystore
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(keyStoreInputStream, null);
//add to known keystore
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keystore);
//default SSL connections are initialized with the keystore above
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustManagers, null);
SSLContext.setDefault(sc);
} catch (IOException | GeneralSecurityException e) {
throw new RuntimeException(e);
}
}
Please see below for a modest improvement on @Sled's code shown above, that turn-back-on method was missing one line, now it passes my tests.请参阅下面对上面显示的@Sled 代码的适度改进,该开启方法缺少一行,现在它通过了我的测试。 This disables HTTPS certificate and hostname spoofing when using RestTemplate in a Spring-Boot version 2 application that uses the default HTTP configuration , NOT configured to use Apache HTTP Client.
在使用默认 HTTP 配置(未配置为使用 Apache HTTP 客户端)的 Spring-Boot 版本 2 应用程序中使用 RestTemplate 时,这将禁用 HTTPS 证书和主机名欺骗。
package org.my.little.spring-boot-v2.app;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
/**
* Disables and enables certificate and host-name checking in
* HttpsURLConnection, the default JVM implementation of the HTTPS/TLS protocol.
* Has no effect on implementations such as Apache Http Client, Ok Http.
*/
public final class SSLUtils {
private static final HostnameVerifier jvmHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
private static final HostnameVerifier trivialHostnameVerifier = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession sslSession) {
return true;
}
};
private static final TrustManager[] UNQUESTIONING_TRUST_MANAGER = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
} };
public static void turnOffSslChecking() throws NoSuchAlgorithmException, KeyManagementException {
HttpsURLConnection.setDefaultHostnameVerifier(trivialHostnameVerifier);
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, UNQUESTIONING_TRUST_MANAGER, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
public static void turnOnSslChecking() throws KeyManagementException, NoSuchAlgorithmException {
HttpsURLConnection.setDefaultHostnameVerifier(jvmHostnameVerifier);
// Return it to the initial state (discovered by reflection, now hardcoded)
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, null, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
private SSLUtils() {
throw new UnsupportedOperationException("Do not instantiate libraries.");
}
}
@Bean(name = "restTemplateByPassSSL")
public RestTemplate restTemplateByPassSSL()
throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
HostnameVerifier hostnameVerifier = (s, sslSession) -> true;
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
return new RestTemplate(requestFactory);
}
Here's a solution where security checking is disabled (for example, conversing with the localhost) Also, some of the solutions I've seen now contain deprecated methods and such.这是禁用安全检查的解决方案(例如,与本地主机对话)此外,我现在看到的一些解决方案包含不推荐使用的方法等。
/**
* @param configFilePath
* @param ipAddress
* @param userId
* @param password
* @throws MalformedURLException
*/
public Upgrade(String aConfigFilePath, String ipAddress, String userId, String password) {
configFilePath = aConfigFilePath;
baseUri = "https://" + ipAddress + ":" + PORT + "/";
restTemplate = new RestTemplate(createSecureTransport(userId, password, ipAddress, PORT));
restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter());
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
}
ClientHttpRequestFactory createSecureTransport(String username,
String password, String host, int port) {
HostnameVerifier nullHostnameVerifier = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password);
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(
new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM), credentials);
HttpClient client = HttpClientBuilder.create()
.setSSLHostnameVerifier(nullHostnameVerifier)
.setSSLContext(createContext())
.setDefaultCredentialsProvider(credentialsProvider).build();
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory(client);
return requestFactory;
}
private SSLContext createContext() {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
} };
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, null);
SSLContext.setDefault(sc);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
return sc;
} catch (Exception e) {
}
return null;
}
Too late but here you have my solution.太晚了,但在这里你有我的解决方案。 With this class you can turn off all ssl verifications in your project.
使用这个 class 你可以关闭你项目中的所有 ssl 验证。
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
@Slf4j
@Component
public class SslWarningRemover {
public SslWarningRemover() {
log.info("Disabling SSL warning...");
try {
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
log.info("SSL verification disabled");
} catch (Exception e) {
log.error("Error while trying to disable SSL verification: " + e.getMessage(), e);
}
log.info("SSL warning process remover has finished!");
}
}
If you want to disable the SSL verification in a single RestTemplate, try this:如果你想在单个 RestTemplate 中禁用 SSL 验证,试试这个:
import java.io.IOException;
import java.net.HttpURLConnection;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class CustomClientHttpRequestFactory extends SimpleClientHttpRequestFactory {
private static final HostnameVerifier PROMISCUOUS_VERIFIER = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
private static final TrustManager[] ALL_CERT_TRUST_MANAGER = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
private static SSLContext ALL_CERT_TRUST_SSLCONTEXT = null;
static {
try {
ALL_CERT_TRUST_SSLCONTEXT = SSLContext.getInstance("SSL");
ALL_CERT_TRUST_SSLCONTEXT.init(null, ALL_CERT_TRUST_MANAGER, new SecureRandom());
} catch (Exception e) {
log.error("Error disabling SSL verification");
log.error(e.getMessage(), e);
}
}
private boolean disableSslVerification = false;
public CustomClientHttpRequestFactory(int connectTimeout, int readTimeout, boolean disableSslVerification) {
this.setConnectTimeout(connectTimeout);
this.setReadTimeout(readTimeout);
this.disableSslVerification = disableSslVerification;
}
@Override
protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
if (disableSslVerification && ALL_CERT_TRUST_SSLCONTEXT != null && connection instanceof HttpsURLConnection) {
((HttpsURLConnection) connection).setHostnameVerifier(PROMISCUOUS_VERIFIER);
((HttpsURLConnection) connection).setSSLSocketFactory(ALL_CERT_TRUST_SSLCONTEXT.getSocketFactory());
}
super.prepareConnection(connection, httpMethod);
}
}
Then, when you instance a RestTemplate object, use this:然后,当您实例化 RestTemplate object 时,请使用:
RestTemplate restTemplate = new RestTemplate(new CustomClientHttpRequestFactory(connectTimeout, readTimeout, disableSslVerification));
with disableSslVerification parameter as true . disableSslVerification参数为true 。
Iknow It is too old to answer, but I couldn't find solution like this.我知道回答太老了,但我找不到这样的解决方案。
The code that worked for me with the jersey client:与球衣客户一起为我工作的代码:
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;
import javax.net.ssl.*;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedHashMap;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
public class Testi {
static {
disableSslVerification();
}
private static void disableSslVerification() {
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
}
public Testi() {
MultivaluedHashMap<String, Object> headers = new MultivaluedHashMap<>();
//... initialize headers
Form form = new Form();
Entity<Form> entity = Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE);
// initialize entity ...
WebTarget target = getWebTarget();
Object responseResult = target.path("api/test/path...").request()
.headers(headers).post(entity, Object.class);
}
public static void main(String args[]) {
new Testi();
}
private WebTarget getWebTarget() {
ClientConfig clientConfig = new ClientConfig();
clientConfig.property(ClientProperties.CONNECT_TIMEOUT, 30000);
clientConfig.property(ClientProperties.READ_TIMEOUT, 30000);
SSLContext sc = getSSLContext();
Client client = ClientBuilder.newBuilder().sslContext(sc).withConfig(clientConfig).build();
WebTarget target = client.target("...url...");
return target;
}
private SSLContext getSSLContext() {
try {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws CertificateException {
}
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
}
};
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
return sc;
} catch (NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
return null;
}
}
In my case, with letsencrypt https, this was caused by using cert.pem
instead of fullchain.pem
as the certificate file on the requested server.在我的情况下,使用letsencrypt https,这是由于使用
cert.pem
而不是fullchain.pem
作为请求服务器上的证书文件造成的。 See this thread for details.有关详细信息,请参阅此线程。
I want to share, at least for myself, my code based on other answers.我想至少为我自己分享我基于其他答案的代码。
// Spring Boot 2.7.5 / Java 11
@PostConstruct
private void onPostConstruct() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
// http://www.chrispad.com/2019/02/disable-certificate-verification-using.html
var sslContext = SSLContexts.custom().loadTrustMaterial((c, at) -> true).build();
var socketFactory = new SSLConnectionSocketFactory(sslContext, (h, s) -> true);
var httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build();
var requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
template = templateBuilder.requestFactory(() -> requestFactory).build();
}
private final RestTemplateBuilder templateBuilder;
private RestTemplate template;:
Disabling certificate checking is the wrong solution, and radically insecure.禁用证书检查是错误的解决方案,而且非常不安全。
The correct solution is to import the self-signed certificate into your truststore.正确的解决方案是将自签名证书导入您的信任库。 An even more correct solution is to get the certificate signed by a CA.
更正确的解决方案是让 CA 签署证书。
If this is 'only for testing' it is still necessary to test the production configuration.如果这“仅用于测试”,则仍然需要测试生产配置。 Testing something else isn't a test at all, it's just a waste of time.
测试其他东西根本不是测试,它只是浪费时间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.