All,
I am trying to take
a SOAP message with an attachment that I generate programmatically and using
WSS4J sign both the SOAP envelope and the attachment
and am having no
luck.
I have a class that
generates a SOAPMessage with one attachment, the SOAPMessage when written to
disk looks
like this:
------=_Part_0_31706449.1132072650953
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: binary
Content-Id: <EE4F345108731450517EC35D0A924646>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w33.org/2001/XMLSchema-instance">
<soapenv:Body>
<mesa:LightweightJDBCAdapterQuery xmlns:mesa="http://www.stercomm.com/mesa">
<mesa:sql>show tables</mesa:sql>
<mesa:pool>mysqlPool</mesa:pool>
<mesa:result_name>theResult</mesa:result_name>
<mesa:row_name>theRow</mesa:row_name>
<mesa:query_type>SELECT</mesa:query_type>
</mesa:LightweightJDBCAdapterQuery>
</soapenv:Body>
</soapenv:Envelope>
------=_Part_0_31706449.1132072650953
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-Id: <1132072650772>
<soapenv:Body>
<mesa:LightweightJDBCAdapterQuery xmlns:mesa="http://www.stercomm.com/mesa">
<mesa:sql>show tables</mesa:sql>
<mesa:pool>mysqlPool</mesa:pool>
<mesa:result_name>theResult</mesa:result_name>
<mesa:row_name>theRow</mesa:row_name>
<mesa:query_type>SELECT</mesa:query_type>
</mesa:LightweightJDBCAdapterQuery>
</soapenv:Body>
</soapenv:Envelope>
------=_Part_0_31706449.1132072650953
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-Id: <1132072650772>
This is a very simple text attachment file to use
in basic SOA outbound response creation regression tests.
------=_Part_0_31706449.1132072650953--
=============================================================================================================
Here is the method that takes the SOAPMessage and
signs it
/**
* Sign a soap message.
* We wish to sign both the body and the attachment
* <p/>
*
* @param msg - SOAPMessage object to sign - there is one attachment present
* @param msgStream - the SOAPMessage represented as an input stream
* @return new Signed SOAPMessage
* @throws Exception
*/
private SOAPMessage signSOAPMessage(SOAPMessage msg, InputStream msgStream) {
* Sign a soap message.
* We wish to sign both the body and the attachment
* <p/>
*
* @param msg - SOAPMessage object to sign - there is one attachment present
* @param msgStream - the SOAPMessage represented as an input stream
* @return new Signed SOAPMessage
* @throws Exception
*/
private SOAPMessage signSOAPMessage(SOAPMessage msg, InputStream msgStream) {
Message
signedSOAPMsg=null;
Iterator attachmentsIter=null;
FileInputStream attachmentStream = null;
try {
// create an AxisMessage from the SOAPMessage InputStream
// pass false for arg2 as the msgStream contains the ENTIRE message.
Message axisMessage = new Message(msgStream, false, msg.getMimeHeaders());
Iterator attachmentsIter=null;
FileInputStream attachmentStream = null;
try {
// create an AxisMessage from the SOAPMessage InputStream
// pass false for arg2 as the msgStream contains the ENTIRE message.
Message axisMessage = new Message(msgStream, false, msg.getMimeHeaders());
SOAPEnvelope unsignedEnvelope =
axisMessage.getSOAPEnvelope();
Document doc =
unsignedEnvelope.getAsDocument();
// WSSignEnvelope signs a SOAP envelope
according to the
// WS Specification (X509 profile) and adds the signature data
// to the envelope.
WSSignEnvelope signer = new WSSignEnvelope();
// WS Specification (X509 profile) and adds the signature data
// to the envelope.
WSSignEnvelope signer = new WSSignEnvelope();
String alias =
"16c73ab6-b892-458f-abf5-2f875f74882e";
String password = "security";
signer.setUserInfo(alias, password);
String password = "security";
signer.setUserInfo(alias, password);
// create
a vector of WSEncryptPart parts to sign, both the soap body and the
attachments
SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(unsignedEnvelope);
Vector parts = new Vector();
SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(unsignedEnvelope);
Vector parts = new Vector();
// add the body
part
String localPart = soapConstants.getBodyQName().getLocalPart();
String envelopeURI = soapConstants.getEnvelopeURI();
WSEncryptionPart body = new WSEncryptionPart(localPart, envelopeURI, "Content");
String localPart = soapConstants.getBodyQName().getLocalPart();
String envelopeURI = soapConstants.getEnvelopeURI();
WSEncryptionPart body = new WSEncryptionPart(localPart, envelopeURI, "Content");
parts.add(body);
// how to add the
attachment part?????
signer.setParts(parts);
signer.setParts(parts);
// The "build" method, creates the
signed SOAP envelope.
// It takes a SOAP Envelope as a W3C Document and adds
// a WSS Signature header to it. The signed elements
// depend on the signature parts that are specified by
// the WSBaseMessage.setParts(java.util.Vector parts)
// method. By default, SOAP Body is signed.
// The "crypto" parameter is the object that implements
// access to the keystore and handling of certificates.
// A default implementation is included:
// org.apache.ws.security.components.crypto.Merlin
// It takes a SOAP Envelope as a W3C Document and adds
// a WSS Signature header to it. The signed elements
// depend on the signature parts that are specified by
// the WSBaseMessage.setParts(java.util.Vector parts)
// method. By default, SOAP Body is signed.
// The "crypto" parameter is the object that implements
// access to the keystore and handling of certificates.
// A default implementation is included:
// org.apache.ws.security.components.crypto.Merlin
Document signedDoc = signer.build(doc,
CryptoFactory.getInstance());
// Convert the signed document into a
SOAP message.
signedSOAPMsg = (org.apache.axis.Message) AxisUtil
.toSOAPMessage(signedDoc);
} catch (Exception e) {
e.printStackTrace();
}
return signedSOAPMsg;
}
signedSOAPMsg = (org.apache.axis.Message) AxisUtil
.toSOAPMessage(signedDoc);
} catch (Exception e) {
e.printStackTrace();
}
return signedSOAPMsg;
}
======================================================================================================
How do you add the attachment as a WSEncryptionPart
so that the WSSignEnvelope object will also
sign the attachment? I get a
signed soap message back but it contains only a signature on the body
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w33.org/2001/XMLSchema-instance">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1"><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>
<ds:Reference URI="#id-28881851">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
<ds:DigestValue>EPBz8LncSCtztyJqa6pQ3L0gZGk=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
odXsDPaJ3YTCOe9pldOpPyxSqMKFRj5xk0+Jrd4TUq58SknkRYVPVmo518oaOaqlkim9psUX51lS
hmnpHFyljw==
</ds:SignatureValue>
<ds:KeyInfo Id="KeyId-16109616">
<wsse:SecurityTokenReference xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="STRId-4961129"><ds:X509IssuerSerial>
<ds:X509IssuerName>CN=dims</ds:X509IssuerName>
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1"><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>
<ds:Reference URI="#id-28881851">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
<ds:DigestValue>EPBz8LncSCtztyJqa6pQ3L0gZGk=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
odXsDPaJ3YTCOe9pldOpPyxSqMKFRj5xk0+Jrd4TUq58SknkRYVPVmo518oaOaqlkim9psUX51lS
hmnpHFyljw==
</ds:SignatureValue>
<ds:KeyInfo Id="KeyId-16109616">
<wsse:SecurityTokenReference xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="STRId-4961129"><ds:X509IssuerSerial>
<ds:X509IssuerName>CN=dims</ds:X509IssuerName>
<ds:X509SerialNumber>44369778256217224370984914847992022613</ds:X509SerialNumber>
</ds:X509IssuerSerial></wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature></wsse:Security></soapenv:Header>
<soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-28881851">
<mesa:LightweightJDBCAdapterQuery xmlns:mesa="http://www.stercomm.com/mesa">
<mesa:sql>show tables</mesa:sql>
<mesa:pool>mysqlPool</mesa:pool>
<mesa:result_name>theResult</mesa:result_name>
<mesa:row_name>theRow</mesa:row_name>
<mesa:query_type>SELECT</mesa:query_type>
</mesa:LightweightJDBCAdapterQuery>
</soapenv:Body>
</soapenv:Envelope>
</ds:X509IssuerSerial></wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature></wsse:Security></soapenv:Header>
<soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-28881851">
<mesa:LightweightJDBCAdapterQuery xmlns:mesa="http://www.stercomm.com/mesa">
<mesa:sql>show tables</mesa:sql>
<mesa:pool>mysqlPool</mesa:pool>
<mesa:result_name>theResult</mesa:result_name>
<mesa:row_name>theRow</mesa:row_name>
<mesa:query_type>SELECT</mesa:query_type>
</mesa:LightweightJDBCAdapterQuery>
</soapenv:Body>
</soapenv:Envelope>
=====================================================================
I have looked through the WSS4J signing code and I
cannot see for the life of me how the attachment
would ever get signed.
In scouring the web
I do not see any coverage (so far) of this topic.
Has anybody else run
into this?
Thanks in
advance.
Nick
Mogielnicki
