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

使用Apache CXF调用第三方Web服务遇X509策略解析异常

Apache CXF调用带X509认证/签名/加密的Web服务时策略解析异常解决

问题场景

使用Java Apache CXF生成代理调用第三方Web服务,服务采用X509 Authentication、Signature and Encryption机制保护,调用时抛出如下异常:

Apache CXF Policy Exception Reference to policy "X509 Authentication, Signature and Encryption" could not be resolved

当前尝试代码:

ServiceEnq service=new ServiceEnq(new URL("https://.....Inquiry?wsdl"));

System.out.println("Line2 scuccess!");

InquiryPortType port=service.getInquiryPort();

Client client = ClientProxy.getClient(port);

org.apache.cxf.endpoint.Endpoint endpoint = client.getEndpoint();

HashMap<String, Object> outProps = new HashMap<String, Object>();
outProps.put(WSHandlerConstants.ACTION, "UsernameToken Timestamp Signature Encryption");

outProps.put(WSHandlerConstants.USER, "username1");
outProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, PasswordCallbackHandler.class.getName());

outProps.put(WSHandlerConstants.ENCRYPTION_USER, "public1");
outProps.put(WSHandlerConstants.ENC_PROP_FILE, "publicProp.properties");

outProps.put(WSHandlerConstants.SIGNATURE_USER, "pk"); 
outProps.put(WSHandlerConstants.SIG_PROP_FILE, "pkProp.properties");
outProps.put("timeToLive", "30");

WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
endpoint.getOutInterceptors().add(wssOut);

HashMap<String, Object> inProps = new HashMap<>();
inProps.put(WSHandlerConstants.ACTION, "Encryption Signature Timestamp");
inProps.put(WSHandlerConstants.DEC_PROP_FILE, "publicProp.properties");
inProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, PasswordCallbackHandler.class.getName());
inProps.put(WSHandlerConstants.SIG_PROP_FILE, "pkProp.properties");

WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps);
endpoint.getInInterceptors().add(wssIn);

ObjectFactory fact=new ObjectFactory();
InquiryRequest request=fact.createInquiryRequest();
MessageHeaderIn headerIn=fact.createMessageHeaderIn(); 

// 省略输入参数设置

// 以下代码行抛出异常
InquiryResponse2 res= port.Inquiry(request);

解决方案

1. 禁用CXF自动策略验证

由于已手动配置WSS4J拦截器处理安全逻辑,无需CXF自动解析WSDL中的策略断言,添加以下代码禁用策略验证:

// 针对当前端点禁用策略验证
endpoint.getEndpointInfo().setProperty("disable.policy.validation", Boolean.TRUE);

// 或者全局禁用(适用于所有服务调用)
// System.setProperty("org.apache.cxf.disable.validate.policy", "true");

2. 修正WSS4J配置匹配X509认证要求

当前代码配置了UsernameToken,但服务要求的是X509认证,需调整输出拦截器的ACTION及相关配置:

// 修改输出拦截器的ACTION,移除UsernameToken,保留符合服务要求的安全动作
outProps.put(WSHandlerConstants.ACTION, "Timestamp Signature Encryption");

// 移除UsernameToken相关配置(如果不再需要)
// outProps.remove(WSHandlerConstants.USER);
// outProps.remove(WSHandlerConstants.PASSWORD_TYPE);

// 确保签名/加密使用X509证书对应的密钥库配置正确
// pkProp.properties需包含:
// org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
// org.apache.ws.security.crypto.merlin.keystore.type=JKS
// org.apache.ws.security.crypto.merlin.keystore.password=你的密钥库密码
// org.apache.ws.security.crypto.merlin.keystore.file=密钥库文件路径
// org.apache.ws.security.crypto.merlin.alias=你的X509证书别名

3. 验证WSDL策略引用(可选)

如果必须保留策略验证,需确保WSDL中引用的策略文件可被CXF加载:

  • 检查WSDL中的<wsp:PolicyReference>元素,确认策略URI可访问
  • 将策略文件放置在类路径下,或通过CXF配置指定策略加载路径

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 01:05:52