You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中SoapActionCallback如何配置密钥库与TLSv1

配置方案

SoapActionCallback仅负责设置SOAP请求的Action头,TLS协议、密钥库相关配置属于HTTP传输层逻辑,需要在WebServiceTemplate的消息发送器层面配置,不需要修改现有SOAP调用代码。

第一步:初始化SSL上下文

复用原有加载PKCS12密钥库、初始化TLSv1上下文的逻辑,封装为Spring托管的Bean即可,建议用try-with-resources处理文件流避免资源泄漏:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.SecureRandom;

@Configuration
public class SoapClientConfig {
    private static final String KEYSTORE_PWD = "aaaa";
    private static final String P12_PATH = "1234.p12";
    private static final String TLS_VERSION = "TLSv1";

    @Bean
    public SSLContext customSslContext() throws Exception {
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        try (InputStream is = new ClassPathResource(P12_PATH).getInputStream()) {
            keyStore.load(is, KEYSTORE_PWD.toCharArray());
        }
        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(keyStore, KEYSTORE_PWD.toCharArray());

        SSLContext sslContext = SSLContext.getInstance(TLS_VERSION);
        sslContext.init(kmf.getKeyManagers(), null, new SecureRandom());
        return sslContext;
    }
}

第二步:配置自定义HTTP消息发送器

Spring WS默认使用Apache HttpComponents客户端发送HTTP请求,需要把上面生成的SSLContext注入到客户端中,强制使用TLSv1协议:

import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClients;
import org.springframework.ws.transport.http.HttpComponentsMessageSender;

@Bean
public HttpComponentsMessageSender soapMessageSender(SSLContext customSslContext) {
    // 指定仅支持TLSv1协议,和原有逻辑对齐
    SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
            customSslContext,
            new String[]{TLS_VERSION},
            null,
            SSLConnectionSocketFactory.getDefaultHostnameVerifier()
    );
    HttpClient httpClient = HttpClients.custom()
            .setSSLSocketFactory(socketFactory)
            .build();
    return new HttpComponentsMessageSender(httpClient);
}

如果测试环境存在域名不匹配的问题,可以临时把域名校验器替换为NoopHostnameVerifier.INSTANCE,生产环境必须使用默认域名校验器避免中间人攻击风险。

第三步:将消息发送器绑定到WebServiceTemplate

配置WebServiceTemplate Bean时注入自定义的消息发送器,之后所有通过该实例发起的SOAP请求都会自动加载p12密钥库、使用TLSv1协议建立连接:

import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.ws.client.core.WebServiceTemplate;

@Bean
public WebServiceTemplate webServiceTemplate(Jaxb2Marshaller marshaller, HttpComponentsMessageSender soapMessageSender) {
    WebServiceTemplate template = new WebServiceTemplate();
    template.setMarshaller(marshaller);
    template.setUnmarshaller(marshaller);
    template.setDefaultUri("https://test.com.asmx?WSDL");
    template.setMessageSender(soapMessageSender);
    return template;
}

调用逻辑保持不变

配置完成后,原有的调用代码不需要做任何修改即可正常工作:

ProvaResponse response = (ProvaResponse) getWebServiceTemplate().marshalSendAndReceive(
        request,
        new SoapActionCallback("http://www.test.com/Prova")
);

提示:TLSv1属于已废弃的不安全协议,服务端支持的话优先升级到TLSv1.2及以上版本。如果服务端使用自签名证书,还需要在SSLContext初始化时添加自定义TrustManager加载信任证书。

内容的提问来源于stack exchange,提问作者Andrea Rovelli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 15:18:13