Spring RestTemplate로 SSL 인증서 검사를 비활성화하는 방법?
저는 우리 테스트가 Simple을 사용하여 임베디드 HTTPS 서버를 런칭하는 통합 테스트를 작성하려고 합니다.를 사용하여 자체 서명 인증서를 만들었고 브라우저(특히 Chrome)를 사용하여 서버에 액세스할 수 있으며, 자체 서명 인증서에 대한 경고가 표시됩니다.
그러나 Spring RestTemplate를 사용하여 연결하려고 하면 ResourceAccess가 나타납니다.예외:
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
다른 질문들과 블로그 게시물들로부터 나는 그들을 대체하기 위한 조언을 보았습니다.HostnameVerifier
비슷한 것을 가지고
private static final HostnameVerifier PROMISCUOUS_VERIFIER = ( s, sslSession ) -> true;
그리고 전세계적으로 그리고 전세계적으로 설정했습니다.RestTemplate
자체:
HttpsURLConnection.setDefaultHostnameVerifier( PROMISCUOUS_VERIFIER );
...그리고 그 위에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);
}
});
그런데도 위의 오류가 계속 발생하고 있습니다.어떻게 하면 빠져나갈 수 있을까요?
- 장치 테스트 외부에 인증서를 로컬로 설치하는 것은 옵션이 아닙니다. 그렇게 되면 모든 개발 기계 및 빌드 서버에 수동으로 설치해야 하고 붉은 테이프가 눈사태를 일으킬 수 있기 때문입니다.
- 맨 위에 있는 라이브러리를 테스트하고 있기 때문에 SSL이 필요합니다.
RestTemplate
정확하게 구성하고 있습니다.
저는 Java 8(단, 7)과 Spring 4.0.3을 사용하고 있습니다.
저는 이 방향으로 저를 이끄는 소스에 대한 링크가 여전히 있었으면 좋겠지만, 이것이 결국 저를 위해 작동하게 된 코드입니다.자바Doc for X509TrustManager를 검토해보면 다음과 같이 보입니다.TrustManager
작업은 성공적인 검증 시 아무것도 반환하지 않고, 그렇지 않으면 예외를 부여합니다.따라서 null 구현을 사용하면 성공적인 검증으로 처리됩니다.그런 다음 다른 모든 구현을 제거합니다.
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.");
}
}
이 질문을 발견하고 단위 테스트에만 적합한 다른 솔루션이 필요한 다른 개발자를 위해:
제가 해결책이 아닌 블로그에서 발견했습니다!블로그 소유자에게 공을 돌립니다.
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);
위에 제시된 @Sled의 코드에 대한 약간의 개선을 위해 아래를 참조하시기 바랍니다. 그 턴-백 방식은 한 줄이 빠졌고, 지금은 제 테스트를 통과했습니다.그러면 Apache HTTP Client를 사용하도록 구성되지 않은 기본 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);
}
키 저장소를 등록할 수도 있습니다.
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);
}
}
여기에 보안 검사가 비활성화된 솔루션이 있습니다(예: 로컬 호스트와의 대화). 또한 지금 본 솔루션 중 일부는 더 이상 사용하지 않는 메서드 등을 포함하고 있습니다.
/**
* @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;
}
너무 늦었지만 해결책은 여기 있습니다.이 클래스를 사용하면 프로젝트의 모든 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!");
}
}
단일 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);
}
}
그런 다음 RestTemplate 개체를 인스턴스화할 때 다음을 사용합니다.
RestTemplate restTemplate = new RestTemplate(new CustomClientHttpRequestFactory(connectTimeout, readTimeout, disableSslVerification));
disableSslVerification 매개 변수를 true로 지정합니다.
대답하기엔 너무 늙었다는 것을 알지만, 저는 이런 해결책을 찾을 수 없었습니다.
저지 고객과 함께 했던 코드:
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;
}
}
저는 적어도 저 자신을 위해서는 다른 답변을 바탕으로 제 코드를 공유하고 싶습니다.
// 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;:
private static void disableSslVerification() {
try
{
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = 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) {
}
}
};
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// 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);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
https를 하자니 를 https 은, 을 사용해서 입니다.cert.pem
에 대신에fullchain.pem
요청한 서버의 인증서 파일로 지정합니다.자세한 내용은 이 스레드를 참조하십시오.
인증서 검사를 비활성화하는 것은 잘못된 해결책이며 근본적으로 안전하지 않습니다.
올바른 해결책은 자체 서명된 인증서를 트러스트 저장소로 가져오는 것입니다.훨씬 더 정확한 해결책은 CA에서 인증서에 서명하는 것입니다.
'테스트용'인 경우에도 프로덕션 구성을 테스트해야 합니다.다른 것을 테스트하는 것은 전혀 테스트가 아니라 시간 낭비일 뿐입니다.
언급URL : https://stackoverflow.com/questions/23504819/how-to-disable-ssl-certificate-checking-with-spring-resttemplate
'programing' 카테고리의 다른 글
"도커 빌드" 중에 도커 이미지에서 /etc/hosts 파일을 업데이트하는 방법 (0) | 2023.09.14 |
---|---|
"새로운 크로스 플랫폼 PowerShell https://aka.ms/pscore6 을 사용해 보십시오"를 억제합니다. (0) | 2023.09.14 |
워드프레스 SQL: 게시물 카테고리 및 태그 가져오기 (0) | 2023.09.14 |
Oracle SQL에서 테이블 삭제 (0) | 2023.09.14 |
Razor View Engine이 Mono에 적합합니까? (0) | 2023.09.14 |