Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgraded spring 5.3 to 6.1, spring-ws 3.1.7 to 4.0.10. Getting "Cannot find SOAP wrapper for element [xenc:EncryptedData: null]" #1404

Closed
pdotsenko opened this issue Feb 7, 2024 · 11 comments
Assignees

Comments

@pdotsenko
Copy link

Java 17, saaj-impl 3.0.3, NON-spring-boot. I have a spring-ws app with message-level security encrypting SOAP Body content. After upgrade getting this error:

2024-02-06 19:42:48,899 (http-nio-8080-exec-5) DEBUG [org.springframework.ws.transport.http.MessageDispatcherServlet] - Failed to complete request: java.lang.IllegalArgumentException: Cannot find SOAP wrapper for element [xenc:EncryptedData: null]
Feb 06, 2024 7:42:48 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [spring-ws] in context with path [/sides-broker-si] threw exception [Request processing failed: java.lang.IllegalArgumentException: Cannot find SOAP wrapper for element [xenc:EncryptedData: null]] with root cause
java.lang.IllegalArgumentException: Cannot find SOAP wrapper for element [xenc:EncryptedData: null]
at com.sun.xml.messaging.saaj.soap.SOAPDocumentImpl.find(SOAPDocumentImpl.java:590)
at com.sun.xml.messaging.saaj.soap.SOAPDocumentImpl.find(SOAPDocumentImpl.java:578)
at com.sun.xml.messaging.saaj.soap.impl.ElementImpl.getFirstChildElement(ElementImpl.java:643)
at com.sun.xml.messaging.saaj.soap.impl.BodyImpl.getPayloadQName(BodyImpl.java:444)
at com.sun.xml.messaging.saaj.soap.impl.BodyImpl.hasFault(BodyImpl.java:156)
at org.springframework.ws.soap.saaj.SaajSoapBody.hasFault(SaajSoapBody.java:56)
at org.springframework.ws.soap.AbstractSoapMessage.hasFault(AbstractSoapMessage.java:62)
at org.springframework.ws.soap.AbstractSoapMessage.getFaultCode(AbstractSoapMessage.java:68)
at org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:94)
at org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:60)
at org.springframework.ws.transport.http.MessageDispatcherServlet.doService(MessageDispatcherServlet.java:288)
...

This looks similar to #1193, but fixes for that issue don't apply to my environment - I am not running tests, the app is running on Tomcat 10.1.

I would appreciate any help or suggestions. Thanks

@corneil
Copy link
Contributor

corneil commented Feb 20, 2024

@pdotsenko Which other dependencies to you use apart from spring-ws:4.0.10?

@corneil
Copy link
Contributor

corneil commented Feb 20, 2024

@pdotsenko Can you identify any test case that may need to be extended to apply to your usage?

pdotsenko added a commit to pdotsenko/echo-server that referenced this issue Feb 28, 2024
pdotsenko added a commit to pdotsenko/echo-spring-ws-client that referenced this issue Feb 28, 2024
@pdotsenko
Copy link
Author

pdotsenko commented Feb 28, 2024

@corneil,

My dependencies include spring-ws-security:4.0.10. My endpoint extends AbstractStaxStreamPayloadEndpoint which is deprecated, but I couldn't replace with equivalent "@endpoint" style setup. I use org.springframework.ws.soap.security.wss4j2.Wss4jSecurityInterceptor for securing both request and response with "Timestamp Signature Encrypt" actions. I noticed that when I disable the Wss4jSecurityInterceptor, the error goes away.

I think spring-ws-security/src/test/java/org/springframework/ws/soap/security/wss4j2/Wss4jMessageInterceptorEncryptionTestCase.java could be extended to reproduce this issue, but I haven't attempted this.

I put together a small sample to reproduce the problem:
https://github.com/pdotsenko/echo-server/ (server)
and
https://github.com/pdotsenko/echo-spring-ws-client/ (client).

The sample is based on spring-ws-samples echo sample modified to fit my use case.

Thanks for looking at this!

@goetzseb
Copy link

goetzseb commented Apr 9, 2024

Does someone know where this is coming from?
I face the excat same error message but with a less sophisticated technology stack:

  • Tomcat 9.0
  • JDK 17
  • spring 5.3.32
  • spring-ws and spring-ws-security 3.1.8

It's hard to debug but my IDE indeed shows that in the user data of the document there is no reference to the EncryptedData node at the line where it is required here (com.sun.xml.messaging.saaj.soap.SOAPDocumentImpl):

final javax.xml.soap.Node found = (javax.xml.soap.Node) node.getUserData(SAAJ_NODE);
if (found == null && required) {
    throw new IllegalArgumentException(MessageFormat.format("Cannot find SOAP wrapper for element {0}", node));
}

This in turn causes:

java.lang.IllegalArgumentException: Cannot find SOAP wrapper for element [xenc:EncryptedData: null]
	at com.sun.xml.messaging.saaj.soap.SOAPDocumentImpl.find(SOAPDocumentImpl.java:590)
	at com.sun.xml.messaging.saaj.soap.SOAPDocumentImpl.find(SOAPDocumentImpl.java:578)
	at com.sun.xml.messaging.saaj.soap.impl.ElementImpl.getFirstChildElement(ElementImpl.java:660)
	at com.sun.xml.messaging.saaj.soap.impl.BodyImpl.getPayloadQName(BodyImpl.java:439)
	at com.sun.xml.messaging.saaj.soap.impl.BodyImpl.hasFault(BodyImpl.java:151)
	at org.springframework.ws.soap.saaj.SaajSoapBody.hasFault(SaajSoapBody.java:55)
	at org.springframework.ws.soap.AbstractSoapMessage.hasFault(AbstractSoapMessage.java:62)
	at org.springframework.ws.soap.AbstractSoapMessage.getFaultCode(AbstractSoapMessage.java:68)
	at org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:94)

@pdotsenko
Copy link
Author

pdotsenko commented Apr 9, 2024

@goetzseb and @corneil - I determined that this error is caused by saaj-impl:1.5.3 and happens in both spring 5 and spring 6. I initially thought that the upgrade to spring 6 caused the bug, but was wrong. In spring 5 I was using Axiom soap message factory, but had to switch to Saaj since Axiom is not supported in spring 6 (does not support jakarta XML packages and is not maintained). When I tried using Saaj message factory in a working spring 5 application I received the same error as above.

@goetzseb, you can still use Axiom in Spring 5. Just switch to Axiom soap message factory and it should fix the problem - no other changes should be necessary:

	<bean id="messageFactory"
		class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory">
	</bean>

or
@bean
public AxiomSoapMessageFactory messageFactory() {
return new AxiomSoapMessageFactory();
}

I am using axiom-impl: 1.2.22.

@goetzseb
Copy link

goetzseb commented Apr 10, 2024

@pdotsenko thank you for sharing your thoughts.
We are using SAAJ as well and switching to Axoim does not seem to be a viable option for us. After some try and error I came across that downgrading saaj-impl to 1.3.28 works for my environment. Starting with 1.4.0 I keep getting the above mentioned exception.

EDIT:
I think the breaking change is in com.sun.xml.messaging.saaj.soap.impl.ElementImpl.getFirstChildElement(). Till 1.3.28 this simply returned the first child org.w3c.dom.Element of the body part. Starting with 1.4.0 there is an additional call to (SOAPElement) soapDocument.find(eachChild) which I don't know what it does. But it looks into the document node's userData and finds nothing. I cannot tell whether this is an issue caused by spring-ws or saaj-impl.

@corneil corneil self-assigned this Apr 10, 2024
@pdotsenko
Copy link
Author

Thank you @goetzseb for the workaround for spring 5, I can confirm that my project with spring 5/spring-ws 3.1.8 works after downgrading to saaj-impl 1.3.8, although we prefer Axiom for now.
This is still a problem with spring-ws 4 and spring 6 since it is not compatible with saaj-impl 1.3.8.

@corneil
Copy link
Contributor

corneil commented May 9, 2024

You cannot have code that stradles the Jakarta EE / Java EE boundary. The javax.xml is only in Java EE and Javakarta EE uses jakarta.xml.
So you have to use either Spring Framework 6.x and Spring WS 4.x or Spring Framework 5.x and Spring WS 3.x

@corneil corneil closed this as completed May 9, 2024
@d-casal
Copy link

d-casal commented Aug 30, 2024

@corneil @pdotsenko @goetzseb I've run in the exact same error.

    springVersion = "6.1.11"
    springWSVersion = "4.0.11"

com.sun.xml.messaging.saaj:saaj-impl:3.0.4

Stacktrace:

java.lang.IllegalArgumentException: Cannot find SOAP wrapper for element [xenc:EncryptedData: null]
at com.sun.xml.messaging.saaj.soap.SOAPDocumentImpl.find(SOAPDocumentImpl.java:590)
at com.sun.xml.messaging.saaj.soap.SOAPDocumentImpl.find(SOAPDocumentImpl.java:578)

I would like to keep using the SAAJ. Does anybody have any tips on how to overcome this problem?

@d-casal
Copy link

d-casal commented Sep 9, 2024

Ok, for me it turned out to be some kind of lazy loading problem. I resolved by adding the 2nd line below:

super.secureMessage(soapMessage, messageContext);
soapMessage.getDocument().getChildNodes(); // <-- trigger initialization/population of elements (deferred by lazy loading)

pdotsenko added a commit to pdotsenko/echo-server that referenced this issue Sep 20, 2024
@pdotsenko
Copy link
Author

@d-casal - Your suggestion fixed my issue as well, thanks for sharing!
I updated my sample to reproduce the issue with the workaround fix if anyone wants to look here: https://github.com/pdotsenko/echo-server
@corneil: - This is an on-going issue with spring 6.1.13 and spring-ws 4.0.11, no jakarta/javax boundary is crossed. Although the underlying problem is probably in SAAJ, imho the workaround fix should be added to org.springframework.ws.soap.security.wss4j2).Wss4jSecurityInterceptor.secureMessage(...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants