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

Apache CXF 3.1.10对接WS-SecureConversation微软服务器证书校验问题求助

解决Apache CXF 3.1.10与WS-SecureConversation微软服务器通信的自签名证书校验问题

哦,这个问题我之前帮不少开发者踩过坑——WS-SecureConversation的特性就是它会发起两次独立的调用:一次是主客户端和目标服务器建立连接,另一次是通过内部的STSClient和安全令牌服务(STS)通信。你之前找不到禁用校验的方法,大概率是只配置了主客户端的证书信任,却漏掉了STSClient的配置,毕竟它是个单独的客户端实例,默认会走系统的证书校验规则。

下面给你两种可行的解决方式,分别适用于代码直接配置和Spring XML配置的场景:

代码层面手动配置(适合纯Java代码实现的客户端)

1. 先创建一个信任所有证书的SSL上下文

这个工具方法会生成一个不做任何证书校验的SSL上下文,测试环境用很方便:

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;

public static SSLContext getTrustAllSSLContext() throws Exception {
    // 创建一个信任所有证书的TrustManager
    TrustManager[] trustAllCerts = new TrustManager[]{
        new X509TrustManager() {
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
            @Override
            public void checkClientTrusted(X509Certificate[] certs, String authType) {}
            @Override
            public void checkServerTrusted(X509Certificate[] certs, String authType) {}
        }
    };
    // 初始化SSL上下文
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
    return sslContext;
}

2. 同时配置主客户端和STSClient的SSL属性

当你创建CXF客户端后,需要把刚才的SSL上下文同时应用到主客户端和内部的STSClient上:

// 初始化主客户端工厂
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(YourServiceInterface.class);
factory.setAddress("https://你的微软服务器地址");

// 获取主客户端实例
YourServiceInterface serviceClient = (YourServiceInterface) factory.create();
Client cxfClient = ClientProxy.getClient(serviceClient);

// 获取内部的STSClient
STSClient stsClient = (STSClient) cxfClient.getRequestContext().get(SecurityConstants.STS_CLIENT);

if (stsClient != null) {
    SSLContext sslContext = getTrustAllSSLContext();
    
    // 配置主客户端的HTTP Conduit
    HTTPConduit mainConduit = (HTTPConduit) cxfClient.getConduit();
    TLSClientParameters mainTlsParams = new TLSClientParameters();
    mainTlsParams.setSSLSocketFactory(sslContext.getSocketFactory());
    mainTlsParams.setDisableCNCheck(true); // 可选:禁用主机名和证书CN的匹配校验
    mainConduit.setTlsClientParameters(mainTlsParams);
    
    // 配置STSClient的HTTP Conduit(关键!之前你可能漏掉了这一步)
    HTTPConduit stsConduit = (HTTPConduit) stsClient.getConduit();
    TLSClientParameters stsTlsParams = new TLSClientParameters();
    stsTlsParams.setSSLSocketFactory(sslContext.getSocketFactory());
    stsTlsParams.setDisableCNCheck(true);
    stsConduit.setTlsClientParameters(stsTlsParams);
}

Spring XML配置方式(适合Spring项目)

如果你的项目用Spring管理CXF客户端,可以通过XML统一配置主客户端和STSClient的信任策略:

<!-- 定义信任所有证书的TLS参数 -->
<bean id="trustAllTlsParams" class="org.apache.cxf.configuration.jsse.TLSClientParameters">
    <property name="trustManagers">
        <list>
            <bean class="org.apache.cxf.configuration.jsse.TrustManagerFactoryBean">
                <!-- 测试环境下可直接使用默认配置,生产环境建议导入自签名证书到信任库并指定路径 -->
                <property name="algorithm" value="SunX509"/>
            </bean>
        </list>
    </property>
    <property name="disableCNCheck" value="true"/>
</bean>

<!-- 配置HTTP Conduit的全局配置器 -->
<bean id="globalConduitConfigurer" class="org.apache.cxf.transport.http.HTTPConduitConfigurer">
    <property name="tlsClientParameters" ref="trustAllTlsParams"/>
</bean>

<!-- 配置STSClient,关联全局配置器 -->
<bean id="stsClientBean" class="org.apache.cxf.ws.security.trust.STSClient">
    <property name="wsdlLocation" value="https://你的STS服务器地址/wsdl"/>
    <property name="serviceName" value="STS服务名称"/>
    <property name="endpointName" value="STS端点名称"/>
    <property name="conduitConfigurer" ref="globalConduitConfigurer"/>
</bean>

<!-- 主客户端配置,关联STSClient -->
<jaxws:client id="yourServiceClient" 
              serviceClass="com.yourpackage.YourServiceInterface" 
              address="https://目标微软服务器地址">
    <jaxws:properties>
        <entry key="ws-security.sts.client" value-ref="stsClientBean"/>
        <!-- 其他WS-SecureConversation相关配置 -->
    </jaxws:properties>
</jaxws:client>

重要提醒:禁用证书校验只适合测试环境!生产环境绝对不能这么做,正确的做法是把微软服务器的自签名证书导入到客户端的JVM信任库或者项目自定义的信任库中,避免安全风险。

内容的提问来源于stack exchange,提问作者Myron Uecker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:00:54