简体   繁体   中英

Create Enveloped Signature with CXF and WSS4J

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...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM