如何在使用resttemplate+BufferingClientHTTPPrequestFactory时禁用ssl证书验证

dauxcl2d  于 2021-07-24  发布在  Java
关注(0)|答案(0)|浏览(308)

为了与项目的其他部分保持一致,我需要使用restempate,并且我使用bufferingclienthttpprequestfactory,因为响应被截获并注销了主体。
我所拥有的
在springbootapplication类中

  1. @Bean
  2. public RestTemplate restTemplate(RestTemplateBuilder builder) {
  3. SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
  4. RestTemplate template = builder
  5. .setReadTimeout((int) Duration.ofSeconds(10).toMillis())
  6. .setConnectTimeout((int)Duration.ofSeconds(10).toMillis())
  7. .build();
  8. template.setRequestFactory(new BufferingClientHttpRequestFactory(factory));
  9. List<ClientHttpRequestInterceptor> interceptorList = new ArrayList<ClientHttpRequestInterceptor>();
  10. interceptorList.add(new LoggingInterceptor());
  11. template.setInterceptors(interceptorList);
  12. return template;}

在役

  1. private ResponseEntity exchangeWithEndpointInternal(RequestEntity<?> request) throws IOException {
  2. Instant requestStart = this.getClock().instant();
  3. ResponseEntity response;
  4. response = restTemplate.exchange(request, String.class);
  5. Instant requestEnd = this.getClock().instant();
  6. return response;
  7. }

我尝试的是:
重写bean定义中的verify方法

  1. template.setRequestFactory(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory() {
  2. @Override
  3. protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
  4. if (connection instanceof HttpsURLConnection) {
  5. ((HttpsURLConnection) connection).setHostnameVerifier(new HostnameVerifier() {
  6. @Override
  7. public boolean verify(String hostname, SSLSession session) {
  8. return true;
  9. }
  10. });
  11. }
  12. super.prepareConnection(connection, httpMethod);
  13. }
  14. }));

使用noophostverifier

  1. template.setRequestFactory(new BufferingClientHttpRequestFactory( new SimpleClientHttpRequestFactory() {
  2. @Override
  3. protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
  4. if (connection instanceof HttpsURLConnection) {
  5. ((HttpsURLConnection) connection).setHostnameVerifier(new NoopHostnameVerifier());
  6. }
  7. super.prepareConnection(connection, httpMethod);
  8. }
  9. }));

两个都没有给我我想要的输出,我需要忽略ssl验证,但是我有一个错误:

  1. Caused by: org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://someHost/somePath": 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: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
  2. at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:742)
  3. at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:635)
  4. at com.....exchangeWithEndpointInternal(FreightApiClientViaHttp.java:97)
  5. at com.....exchangeWithEndpoint(FreightApiClientViaHttp.java:77)
  6. ... 73 common frames omitted

有什么想法吗?我很高兴更改工厂,如果我仍然可以读取响应体的多次示例,这是以前使用okhttpclient时使用的,没有resttemplate,类似这样:

  1. final TrustManager[] trustAllCerts = new TrustManager[] {
  2. new X509TrustManager() {
  3. @Override
  4. public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
  5. }
  6. @Override
  7. public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
  8. }
  9. @Override
  10. public java.security.cert.X509Certificate[] getAcceptedIssuers() {
  11. return new java.security.cert.X509Certificate[]{};
  12. }
  13. }
  14. };
  15. // Install the all-trusting trust manager
  16. final SSLContext sslContext = SSLContext.getInstance("SSL");
  17. sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
  18. // Create an ssl socket factory with our all-trusting manager
  19. final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
  20. OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
  21. okHttpClientBuilder.sslSocketFactory(sslSocketFactory, (X509TrustManager)trustAllCerts[0]);
  22. okHttpClientBuilder.hostnameVerifier(new HostnameVerifier() {
  23. @Override
  24. public boolean verify(String hostname, SSLSession session) {
  25. boolean whitelistedDomain = configuration.getSslDomainWhitelist().stream()
  26. .peek(String::trim)
  27. .filter(domain -> domain.equalsIgnoreCase(hostname))
  28. .findAny()
  29. .isPresent();
  30. if (!whitelistedDomain) {
  31. return OkHostnameVerifier.INSTANCE.verify(hostname, session);
  32. } else {
  33. return true;
  34. }
  35. }
  36. });

但我不能用其他技术复制行为。
最后一点注意:当我用curl启动请求时,我得到一个ssl错误,当我添加-k标志时,一切正常。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题