如何使用 Spring WebServiceTemplate 禁用 SSL 证书检查?

问题描述 投票:0回答:3

为了在开发环境中进行测试,我想忽略开发服务器的

https
证书问题。

我的 Web 服务客户端收到 :-

PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

有许多类似的问题可以帮助我找到解决方案,但我想我会在这里为任何需要它的人发布这个特定问题的答案....

java spring web-services ssl
3个回答
13
投票
class UnTrustworthyTrustManager
        implements X509TrustManager
{
    public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
    public void checkServerTrusted(X509Certificate[] arg0, String arg1)throws CertificateException {}
    public X509Certificate[] getAcceptedIssuers() { return null; }
}

然后

setDefaultUri("https://myServer/soapws/ws/");
Source requestSource = new ResourceSource(new ClassPathResource("MyRequest.xml"));
StringResult result = new StringResult();
WebServiceTemplate template = getWebServiceTemplate();

HttpsUrlConnectionMessageSender sender = new HttpsUrlConnectionMessageSender();
sender.setTrustManagers(new TrustManager[] { new UnTrustworthyTrustManager() });
template.setMessageSender(sender);

template.sendSourceAndReceiveToResult(requestSource, result);
System.out.println(result);

(需要 spring-ws-support)


0
投票

如果您想将 SSL 配置为信任所有证书并直接在

SomeService
类中禁用主机名验证,而无需单独的
customizeClient
方法,则可以将设置直接集成到客户端使用中。以下是您如何在一个地方完成此操作:

import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.transport.http.HttpsUrlConnectionMessageSender;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;

public class SomeService {

    private final WebServiceTemplate webServiceTemplate;

    public SomeService() throws Exception {
        this.webServiceTemplate = new WebServiceTemplate();

        // Step 1: Create a trust manager that does not validate certificate chains
        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) {
                }
            }
        };

        // Step 2: Initialize SSLContext with the trust manager
        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

        // Step 3: Create a hostname verifier that allows all hosts
        HostnameVerifier hostnameVerifier = (hostname, session) -> true;

        // Step 4: Create a custom message sender
        HttpsUrlConnectionMessageSender messageSender = new HttpsUrlConnectionMessageSender();
        messageSender.setSslContext(sslContext);
        messageSender.setHostnameVerifier(hostnameVerifier);

        // Step 5: Set the message sender in WebServiceTemplate
        this.webServiceTemplate.setMessageSender(messageSender);
    }

    // Use this WebServiceTemplate to make web service calls
    public void someWebServiceCall() {
        // Example of a web service call
        // Object response = this.webServiceTemplate.marshalSendAndReceive("WebServiceUrl", requestPayload);
    }
}

在上面的代码中:

  • WebServiceTemplate
    SomeService
    的构造函数中初始化。
  • 信任管理器、SSL 上下文和主机名验证器直接在构造函数中设置。
  • someWebServiceCall
    方法是一个占位符,您可以在其中使用
    WebServiceTemplate
    执行 Web 服务调用。

此设置将为

WebServiceTemplate
SomeService
的所有使用应用不安全的 SSL 上下文和主机名验证器。一如既往,请记住安全风险,并将其仅用于开发目的。


0
投票

如果您正在寻找一种更简单的方法来配置

WebServiceTemplate
以信任所有证书并禁用主机名验证,您可以通过扩展
WebServiceGatewaySupport
并直接配置
WebServiceTemplate
来实现。这种方法利用 Spring 的
CommonsHttpMessageSender
,使用更少的自定义代码。

将以下依赖项添加到

pom.xml
CommonsHttpMessageSender

<dependency>
    <groupId>org.springframework.ws</groupId>
    <artifactId>spring-ws-support</artifactId>
    <version>3.1.1</version> <!-- Check for the latest version -->
</dependency>

现在,在您的服务类中,您可以像这样配置

WebServiceTemplate

import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.transport.http.HttpComponentsMessageSender;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.impl.client.HttpClients;

public class SomeService {

    private final WebServiceTemplate webServiceTemplate;

    public SomeService() throws Exception {
        this.webServiceTemplate = new WebServiceTemplate();
        
        // Set up HttpClient which trusts all certificates
        SSLContextBuilder builder = new SSLContextBuilder();
        builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLContext(builder.build())
                .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                .build();

        // Use the HttpComponentsMessageSender which uses the HttpClient
        HttpComponentsMessageSender messageSender = new HttpComponentsMessageSender();
        messageSender.setHttpClient(httpClient);

        // Set the message sender in the WebServiceTemplate
        this.webServiceTemplate.setMessageSender(messageSender);
    }

    public void someWebServiceCall() {
        // Your web service call logic goes here
    }
}

在这个简化的代码中:

  • Apache HttpComponents 中的
    SSLContextBuilder
    用于构建信任所有自签名证书的 SSL 上下文。
  • 使用了
    HttpComponentsMessageSender
    ,它依赖于Apache HttpClient。
  • NoopHostnameVerifier.INSTANCE
    用于禁用主机名验证。

此设置仍然存在安全隐患,只能用于测试或开发环境。对于生产环境,请始终确保正确的 SSL 证书管理和主机名验证。

© www.soinside.com 2019 - 2024. All rights reserved.