我目前正在Apache CXF的帮助下用Java创建SOAP-Client。
我已经从给定的WSDL生成了Service类,并以编程方式配置客户端。(只是为了说清楚,我没有使用Spring配置)。
我打电话的服务要求我发送的每个请求都需要签名。
到目前为止,我所做的是创建我的客户端并添加WSS4JOutInterceptor以便对消息进行签名。
Client client = ClientProxy.getClient(soapService.getRawSoapInterface());
//Actually not sure if this is really needed?
QName signatureQName = new QName("http://www.w3.org/2000/09/xmldsig#", "Signature");
Map<String, Object> properties = new HashMap<String, Object>();
Map<QName, Object> processorMap = new HashMap<QName, Object>();
processorMap.put(WSSecurityEngine.SIGNATURE, signatureQName);
properties.put("wss4j.processor.map", processorMap);
properties.put(WSHandlerConstants.USER, "clientSignatureAlias");
properties.put(WSHandlerConstants.PW_CALLBACK_CLASS, MyPwCallback.class.getName());
properties.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
properties.put(WSHandlerConstants.ACTION, WSHandlerConstants.SIGNATURE);
properties.put(WSHandlerConstants.SIG_PROP_FILE, "client.properties");
properties.put(WSHandlerConstants.ENC_KEY_ID, "X509KeyIdentifier");
WSS4JOutInterceptor wssOutInterceptor = new WSS4JOutInterceptor(properties);
我的client.properties包含:
org.apache.wss4j.crypto.provider=org.apache.wss4j.common.crypto.Merlin
org.apache.wss4j.crypto.merlin.keystore.type=jks
org.apache.wss4j.crypto.merlin.keystore.password=secret
org.apache.wss4j.crypto.merlin.keystore.alias=cert_sig
org.apache.wss4j.crypto.merlin.keystore.file=clientCerts.jks
到目前为止一切顺利,每条消息都已签名。
让我们来解决这个问题: 问题是,拦截器将这些安全标头放入Soap-Request。
<SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="1">
起初我不是他们,第二点是我打电话的服务并不知道,因此正在回答异常。
目前我找不到办法如何避免这种情况,有什么建议吗?
答案 0 :(得分:0)
据我所知,WSS4J根本无法创建Enveloped Signature!
因此我走向另一个方向。我使用Apache Santuario为我的消息创建签名。
我使用CXF的拦截器机制来创建我自己的拦截器,此处提供了此用例的抽象类:How To Modify The Raw XML message of an Outbound CXF Request?。
我可以调用Santuario STAX-API来创建一个有效的签名,这在以下博客中有很好的描述:http://coheigea.blogspot.ie/2014/03/apache-santuario-xml-security-for-java.html
由于我对请求进行了一些进一步修改,因此我能够修改原始字符串。
感谢上帝,SOAP是标准化协议,每个人都在做他想做的事......