2

I'm developing a JAX-WS webservice that must validate incoming SOAP messages according to the XML Digital Signature specification. I have to manipulate incoming massages to match some transformations made to the reference beferore signing and not reported in the XML document. I use JDOM to do this. I'm noticing a strange behaviour, I can validate the very first incoming message but then validation fails on subsequent messages (on both signature and reference). If i restart the Application Server (Websphere) i can validate the first message. Is this issue related to dirty data shared among subsequnt web service invocations?

Here is the SOAP Handler implementation:

@Override
public boolean handleMessage(SOAPMessageContext messageContext) {

    // get the message from the context 
    SOAPMessage message = messageContext.getMessage(); 

    // is an outgoing message?
    Boolean isOutgoing = (Boolean) messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

    if(!isOutgoing){
        // incoming message...

        // Retrieve the SOAP part of the incoming message
        SOAPPart soapPart = message.getSOAPPart();

        InputStream inStream = null;

        try {


            Document doc = null;           
            // Retrieve the SOAP Envelope of the incoming message
            Source source = soapPart.getContent();  

            inStream = ((StreamSource)source).getInputStream();
            // Instantiate a Document containing the SOAP Envelope
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            DocumentBuilder db = dbf.newDocumentBuilder();
            doc = db.parse(inStream); 

            // Use JDOM to retrieve the CommandMessage element and add the xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" namespace declaration
            org.jdom2.input.DOMBuilder jdomBuilder = new org.jdom2.input.DOMBuilder();                  
            org.jdom2.Document jdomDocument = jdomBuilder.build(doc);
            org.jdom2.Element jdomBodyElement = jdomDocument.getRootElement().getChild("Body", org.jdom2.Namespace.getNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/"));              
            org.jdom2.Element jdomCommandMessageElement = jdomBodyElement.getChild("CommandMessage", org.jdom2.Namespace.getNamespace("", "http://www.cryptomathic.com/ckms"));             
            jdomCommandMessageElement.addNamespaceDeclaration(org.jdom2.Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"));
            // Instantiate W3C Document to be validated
            org.jdom2.Document jdomSignedDocument = new org.jdom2.Document(jdomCommandMessageElement.detach());     
            org.jdom2.output.DOMOutputter outputter = new org.jdom2.output.DOMOutputter();
            Document signedDocument = outputter.output(jdomSignedDocument);
            // Find Signature element
            NodeList nl = signedDocument.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");



            // Create a DOMValidateContext and specify a KeyValue KeySelector and document context
            DOMValidateContext valContext = new DOMValidateContext(new KeyValueKeySelector(), nl.item(0)); 

            // Create a DOM XMLSignatureFactory that will be used to unmarshal the 
            // document containing the XMLSignature 
            XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");

            // unmarshal the XMLSignature
            XMLSignature signature = fac.unmarshalXMLSignature(valContext);

            boolean coreValidity = signature.validate(valContext);                                      

            // Check core validation status
            if (coreValidity == false) {
                System.out.println("Signature failed core validation"); 
                boolean sv = signature.getSignatureValue().validate(valContext);
                System.out.println("signature validation status: " + sv);
                // check the validation status of each Reference
                Iterator i = signature.getSignedInfo().getReferences().iterator();
                for (int j=0; i.hasNext(); j++) {
                    Reference ref = (Reference) i.next();
                    boolean refValid = ref.validate(valContext);
                    System.out.println("ref["+j+"] validity status: " + refValid);
                }
            } else {
                System.out.println("Signature passed core validation");
            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                inStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }


    }

    return true; 
}

And here is the console output for the first request:

Signature passed core validation

But for subsequent requests:

Signature failed core validation

signature validation status: false

ref[0] validity status: false

Regards, Giovanni

dascolagi
  • 107
  • 2
  • 12
  • I narrowed the problem down to how the Application Server passes SOAP Messages to the SOAP Handler. I asked a new question: http://stackoverflow.com/questions/13642167/jax-ws-websphere-as-8-5-and-xml-digital-signature – dascolagi Nov 30 '12 at 09:46

0 Answers0