I have used CXF 3.0.1 for soap implementation and for digital signature I have used wss4j-WS-security-common 3.0.1 and CXF-rt-WS-security 3.0.1. By adding outinterceptor in non-spring settings and along with crypto.merlin properties, I do the digital signature. Now according to the output that is obtained, my webservice provider asks for a BASE64 binary value of X509Data tag. To Summarize I want to replace this:
<ds:KeyInfo Id="...">
<wsse:SecurityTokenReference wsu:Id="...">
<ds:X509Data>
<ds:X509IssuerSerial>
<ds:X509IssuerName>C=...,O=...,CN=....</ds:X509IssuerName>
<ds:X509SerialNumber>70391139840......</ds:X509SerialNumber>
</ds:X509IssuerSerial>
</ds:X509Data>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
With this one:
<KeyInfo>
<X509Data>
<X509Certificate>MIIE4zCCA8ugAwIBAgI...</X509Certificate>
</X509Data>
</KeyInfo>
My current complete output is:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header>
<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="true">
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
Id="SIG-0ce2ba1e-9382-4b99-918f-40fe35c0bcd6">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
PrefixList="soap"/>
</ds:CanonicalizationMethod>
<ds:SignatureMethod
Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#id-f2a96bde-6b41-4283-9fcd-703eca4fd795">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
<ec:InclusiveNamespaces
xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
PrefixList=""/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>nIHemuhLTu4c/drCPaK1is/.....</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
R3Of2Bf60qeSHFyUf5Op7TCGIwJWnhuyHWTNUxNRNLzye6Qi0YeVXTwb0WF9Nesizs16Y...
</ds:SignatureValue>
<ds:KeyInfo Id="KI-38c8124d-967f-4075-99c3-dca94b7d15e9">
<wsse:SecurityTokenReference wsu:Id="STR-9defa6fa-794a-40a3-a57d-2bb1335cbfb6">
<ds:X509Data>
<ds:X509IssuerSerial>
<ds:X509IssuerName>C=...,O=...,CN=....</ds:X509IssuerName>
<ds:X509SerialNumber>70391139840......</ds:X509SerialNumber>
</ds:X509IssuerSerial>
</ds:X509Data>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</soap:Header>
</soap:Envelope>
output that I want to be shown:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header>
<AuthHeader xmlns="http://tempuri.org/">
<UserName>*</UserName>
<Password>*</Password>
</AuthHeader>
</soap:Header>
<soap:Body>
...
</soap:Body>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
<DigestValue>yPt/HXyJyVi1GFFoBb52sTwpaQscONr6QQ2wW....</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>u+XmtuZRW1pqfnIaExnheNGMgg...</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>MIIE4zCCA8ugAwIBAgI...</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
</soap:Envelope>
This is my Java client code:
org.apache.cxf.endpoint.Client client =ClientProxy.getClient(ServicesSoap);
client.getOutInterceptors().add(new SAAJOutInterceptor());
org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint();
Map<String,Object> outProps = new HashMap<String,Object>();
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
cxfEndpoint.getOutInterceptors().add(wssOut);
outProps.put(WSHandlerConstants.ACTION, "Signature");
outProps.put(WSHandlerConstants.USER, "1");
outProps.put(WSHandlerConstants.SIG_PROP_FILE,"crypto.properties");
outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,
ClientPasswordCallback.class.getName());
outProps.put(WSHandlerConstants.SIG_DIGEST_ALGO, "http://www.w3.org/2001/04/xmlenc#sha256");
outProps.put(WSHandlerConstants.MUST_UNDERSTAND, "true");
outProps.put(WSHandlerConstants.SIG_ALGO, "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
outProps.put(WSHandlerConstants.USE_SINGLE_CERTIFICATE, "false");
outProps.put("SecurityToken", "wsse:Base64Binary");
crypto.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.file=/home/...
org.apache.ws.security.crypto.merlin.keystore.alias=1
org.apache.ws.security.crypto.merlin.keystore.password=...
I have searched a lot about this problem. two approaches to solve this problem are using Apache CXF-SAML and also if you want to use wss4j, you can send your request to someone who Authorized your certificate with the name of tags that you tell them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With