使用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
相关产品推荐
相关产品推荐

