I am currently creating a SOAP-Client in Java with help of Apache CXF.
I've generated the Service classes from a given WSDL and configure the client programmatically.(Just to make clear, that I'm not using Spring configuration).
The service I'm calling has the requirement that each Request I send, needs to be signed.
What I did so far is creating my client and add the WSS4JOutInterceptor in order to sign the message.
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);
My client.properties contains:
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
So far so good, and each Message is getting signed.
Lets get to the issue: The Problem is, that The interceptor is putting these Security Headers into the 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">
At first I don't them, second point is that the service I am calling doesn't know them and therefore is answering with an exception.
Currently I cannot find a way how to avoid this, any suggestions?
As far as I understood, WSS4J is not able to create an Enveloped Signature at all!
Therefore I moved into another direction. I used Apache Santuario in order to create a Signature for my message.
I used the Intercepor mechanism of CXF to create my own interceptor, an abstract class for this usecase is provided here: How To Modify The Raw XML message of an Outbound CXF Request? .
There I was able to call the Santuario STAX-API to create an valid signature, this is described very good in the following blog: http://coheigea.blogspot.ie/2014/03/apache-santuario-xml-security-for-java.html
Since I had some further modifications on the request, I was able to modify the raw String.
Thank god that SOAP is standardized protocoll and everybody is doing what he wants to...