1616
1717package  org .springframework .ws .soap .security .wss4j ;
1818
19+ import  java .io .ByteArrayInputStream ;
20+ import  java .io .ByteArrayOutputStream ;
1921import  java .io .IOException ;
2022import  java .security .Principal ;
2123import  java .security .cert .X509Certificate ;
2224import  java .util .Vector ;
2325import  javax .security .auth .callback .Callback ;
2426import  javax .security .auth .callback .CallbackHandler ;
2527import  javax .security .auth .callback .UnsupportedCallbackException ;
26- import  javax .xml .soap .SOAPException ;
28+ import  javax .xml .soap .MessageFactory ;
2729
2830import  org .apache .axiom .soap .SOAPEnvelope ;
2931import  org .apache .axiom .soap .SOAPFactory ;
4446import  org .springframework .beans .factory .InitializingBean ;
4547import  org .springframework .util .Assert ;
4648import  org .springframework .util .StringUtils ;
49+ import  org .springframework .ws .context .DefaultMessageContext ;
4750import  org .springframework .ws .context .MessageContext ;
4851import  org .springframework .ws .soap .SoapMessage ;
4952import  org .springframework .ws .soap .axiom .AxiomSoapMessage ;
5053import  org .springframework .ws .soap .axiom .support .AxiomUtils ;
5154import  org .springframework .ws .soap .saaj .SaajSoapMessage ;
5255import  org .springframework .ws .soap .saaj .SaajSoapMessageException ;
56+ import  org .springframework .ws .soap .saaj .SaajSoapMessageFactory ;
5357import  org .springframework .ws .soap .security .AbstractWsSecurityInterceptor ;
5458import  org .springframework .ws .soap .security .WsSecuritySecurementException ;
5559import  org .springframework .ws .soap .security .WsSecurityValidationException ;
@@ -440,7 +444,7 @@ protected void secureMessage(SoapMessage soapMessage, MessageContext messageCont
440444        }
441445        RequestData  requestData  = initializeRequestData (messageContext );
442446
443-         Document  envelopeAsDocument  = toDocument (soapMessage );
447+         Document  envelopeAsDocument  = toDocument (soapMessage ,  messageContext );
444448        try  {
445449            // In case on signature confirmation with no other securement 
446450            // action, we need to pass an empty securementActionsVector to avoid 
@@ -485,7 +489,7 @@ protected void validateMessage(SoapMessage soapMessage, MessageContext messageCo
485489            return ;
486490        }
487491
488-         Document  envelopeAsDocument  = toDocument (soapMessage );
492+         Document  envelopeAsDocument  = toDocument (soapMessage ,  messageContext );
489493
490494        // Header processing 
491495        WSSecurityEngine  securityEngine  = WSSecurityEngine .getInstance ();
@@ -590,16 +594,27 @@ private void processPrincipal(Vector results) {
590594    }
591595
592596    /** Converts the given {@link SoapMessage} into a {@link Document}. */ 
593-     private  Document  toDocument (SoapMessage  soapMessage ) {
597+     private  Document  toDocument (SoapMessage  soapMessage ,  MessageContext   messageContext ) {
594598        if  (soapMessage  instanceof  SaajSoapMessage ) {
595-             javax .xml .soap .SOAPMessage  saajMessage  = ((SaajSoapMessage ) soapMessage ).getSaajMessage ();
599+             SaajSoapMessage  saajSoapMessage  = (SaajSoapMessage ) soapMessage ;
600+             // return saajSoapMessage.getSaajMessage().getSOAPPart(); // does not work, see SWS-345 
601+             Assert .isInstanceOf (DefaultMessageContext .class , messageContext );
602+             DefaultMessageContext  defaultMessageContext  = (DefaultMessageContext ) messageContext ;
603+             Assert .isInstanceOf (SaajSoapMessageFactory .class , defaultMessageContext .getMessageFactory ());
604+             MessageFactory  messageFactory  =
605+                     ((SaajSoapMessageFactory ) defaultMessageContext .getMessageFactory ()).getMessageFactory ();
596606            try  {
597-                 saajMessage .saveChanges ();
607+                 ByteArrayOutputStream  bos  = new  ByteArrayOutputStream ();
608+                 saajSoapMessage .writeTo (bos );
609+                 ByteArrayInputStream  bis  = new  ByteArrayInputStream (bos .toByteArray ());
610+                 javax .xml .soap .SOAPMessage  saajMessage  =
611+                         messageFactory .createMessage (saajSoapMessage .getSaajMessage ().getMimeHeaders (), bis );
612+                 saajSoapMessage .setSaajMessage (saajMessage );
613+                 return  saajMessage .getSOAPPart ();
598614            }
599-             catch  (SOAPException  ex ) {
615+             catch  (Exception  ex ) {
600616                throw  new  SaajSoapMessageException ("Could not save changes" , ex );
601617            }
602-             return  saajMessage .getSOAPPart ();
603618        }
604619        else  if  (soapMessage  instanceof  AxiomSoapMessage ) {
605620            AxiomSoapMessage  axiomMessage  = (AxiomSoapMessage ) soapMessage ;
@@ -612,20 +627,10 @@ else if (soapMessage instanceof AxiomSoapMessage) {
612627
613628    /** 
614629     * Replaces the contents of the given {@link SoapMessage} with that of the document parameter. Only required when 
615-      * using Axiom, since the document returned by {@link #toDocument(org.springframework.ws.soap.SoapMessage)} is live 
616-      * for a {@link SaajSoapMessage}. 
630+      * using Axiom, since the document returned by {@link #toDocument} is live for a {@link SaajSoapMessage}. 
617631     */ 
618632    private  void  replaceMessage (SoapMessage  soapMessage , Document  envelope ) {
619-         if  (soapMessage  instanceof  SaajSoapMessage ) {
620-             javax .xml .soap .SOAPMessage  saajMessage  = ((SaajSoapMessage ) soapMessage ).getSaajMessage ();
621-             try  {
622-                 saajMessage .saveChanges ();
623-             }
624-             catch  (SOAPException  ex ) {
625-                 throw  new  SaajSoapMessageException ("Could not save changes" , ex );
626-             }
627-         }
628-         else  if  (soapMessage  instanceof  AxiomSoapMessage ) {
633+         if  (soapMessage  instanceof  AxiomSoapMessage ) {
629634            // construct a new Axiom message with the processed envelope 
630635            AxiomSoapMessage  axiomMessage  = (AxiomSoapMessage ) soapMessage ;
631636            SOAPEnvelope  envelopeFromDOMDocument  = AxiomUtils .toEnvelope (envelope );
0 commit comments