How to disable SSL certificate checking with Spring RestTemplate?(使用resttemplate访问https时禁用证书检查)
How to disable SSL certificate checking with Spring RestTemplate?(使用resttemplate访问https时禁用证书检查)
*********************************************************************************************
I am trying to write an integration test where our test launches an embedded HTTPS server using Simple. 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).
However, when I try to connect using Spring RestTemplate, I get a 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
- private static final HostnameVerifier PROMISCUOUS_VERIFIER = ( s, sslSession ) -> true;
And I've set it both globally and on the RestTemplate
itself:
- HttpsURLConnection.setDefaultHostnameVerifier( PROMISCUOUS_VERIFIER );
..and on the RestTemplate
itself:
- 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?
- Installing the certificate locally outside of the unit test is not an option as then it would need to get installed manually on every dev machine and build server and would cause an avalanche of red tape.
- We need SSL since we are testing a library that sits on top of
RestTemplate
and that we are configuring it correctly.
I am using Java 8 (but could use 7) and Spring 4.0.3 .
answer1:
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. Thus, with a null implementation, it is treated as a successful validation. Then you remove all other implementations.
- import javax.net.ssl.*;
- import java.security.*;
- import java.security.cert.CertificateException;
- 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.");
- }
- }
answer2:
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);
- }
- }
answer3:
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;
- }
answer4(可以工作):
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);
answer5:
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.
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.
How to disable SSL certificate checking with Spring RestTemplate?(使用resttemplate访问https时禁用证书检查)的更多相关文章
- PHP出现SSL certificate:unable to get local issuer certificate的解决办法
当本地curl需要访问https时,如果没有配置证书,会出现SSL certificate: unable to get local issuer certificate错误信息. 解决办法: 1.下 ...
- C# 访问https 未能创建 SSL/TLS 安全通道
C# 访问https请求被中止: 未能创建 SSL/TLS 安全通道(Could not create SSL/TLS secure channel) 一般GetResponse可以直接访问https ...
- 使用 OpenSSL为WindowsServer远程桌面(RDP)创建自签名证书 (Self-signed SSL certificate)
前言 笔者查阅很多资料,才写成此文章,如有错误,请读者们及时提出. 一般大家使用远程桌面(Remote Desktop)连接Windows Server时,总会有一个警告提示,如图1 图1 出现此警告 ...
- SSL certificate problem unable to get local issuer certificate解决办法
SSL certificate problem unable to get local issuer certificate 解决办法: 下载:ca-bundle.crt 将它放在自己的wamp或者x ...
- How To Set Up Apache with a Free Signed SSL Certificate on a VPS
Prerequisites Before we get started, here are the web tools you need for this tutorial: Google Chrom ...
- How To Create a SSL Certificate on Apache for CentOS 6
About Self-Signed Certificates 自签证书.一个SSL证书,是加密网站的信息,并创建更安全的链接的一种方式.附加地,证书可以给网站浏览者显示VPS的的身份证明信息.如果一个 ...
- Configure custom SSL certificate for RDP on Windows Server 2012 in Remote Administration mode
Q: So the release of Windows Server 2012 has removed a lot of the old Remote Desktop related configu ...
- (转)How to renew your Apple Push Notification Push SSL Certificate
转自:https://blog.serverdensity.com/how-to-renew-your-apple-push-notification-push-ssl-certificate/ It ...
- 执行Git命令时出现 SSL certificate problem 的解决办法
比如我在windows下用git clone gitURL 就提示 SSL certificate problem: self signed certificate 这种问题,在windows下出现 ...
随机推荐
- Ubuntu菜鸟入门(十三)—— 切换软件源
默认中国服务器,我们把它切换成aliyun的. 在设置--软件和更新里--下载自--其他站点--中国--http://mirrors.aliyun.com/ubuntu 先把所有软件源和软件更新到最新 ...
- Sqlserver大数据量分区表创建
/* 逆向删除对象 DROP PARTITION SCHEME [PS_BasicPolicy2014]; DROP PARTITION FUNCTION [PF_BasicPolicy2014]; ...
- 【Struts2】自定义拦截器interceptors
下面给一张图片表示Struts2拦截器的处理流程. 通过这个流程图,我们可以看出一个完整的请求大概的过程为: 请求 -->filter 控制器 --> 拦截器 1/ 拦截器 2--> ...
- Linux下使用Nexus搭建Maven私服
在开发过程中,有时候会使用到公司内部的一些开发包,显然把这些包放在外部是不合适的.另外,由于项目一直在开发中,这些内部的依赖可能也在不断的更新.可以通过搭建公司内部的Maven服务器,将第三方和内部的 ...
- Smarty标签运算,控制结构[if,for,foreach,section,while]
Smarty标签运算: 在页面上做简单的运算[temp5.html] 条件判断if 循环结构 for foreach用得比较多,foreach例子从数据库取出的数据 section功能和foreach ...
- xtrabackup-增量备份
增量备份之所以能工作是因为每个innodb的page都包含日志序列号(LSN).LSN是整个数据库的版本号. 增量备份会拷贝那些LSN比备份开始时新的页.有两种算法用来计算查找这些页:第一种,支持所有 ...
- debian 8 解压安装mysql(版本5.7.19)
debian 8 解压安装mysql(版本5.7.19)一.下载 根据目标主机的型号官网下载mysql安装包如: mysql-server_5.7.19-1debian8_amd64.deb-bund ...
- NTC电阻抑制冷机启动浪涌电流
开关电源高压直流回路中常用串联负温度系数热敏限流电阻器(NTC)的方法抑制开机浪涌电流,然而这种简单的方法具有很多缺点:如NTC电阻器的限流效果受环境温度影响较大.限流效果在短暂的输入主电网中断(约几 ...
- 【转载】Java导入导出excel
转自:https://blog.csdn.net/jerehedu/article/details/45195359 目前,比较常用的实现Java导入.导出Excel的技术有两种Jakarta POI ...
- 王勇详谈 Linux Deepin 背后的故事
(Linux Deepin最近发布了12.12版本.其也许是国内第一款比较优秀的桌面Linux系统.在此向致力于研发国产OS系统的猿人们表示敬意.虽然Deepin只是基于Ubuntu在桌面应用和UI方 ...