We have a Spring boot app that receives signed SOAP messages and have found that spring-security fails to verify the signature of the body if the envelope and body has a default namespace i.e. without a prefix (Se example message below).
The problem is that SaajSoapMessage.getDocument() automatically adds a default prefix (SOAP-ENV) to the Body tag, if doesn't have a prefix already. That has the effect that the calculated digest of the body doesn't match the value in the security header and causes the signature validation to fail.
We solved by it by overriding validateMessage with a new implementation that catches WsSecurityValidationException and if the messages has an invalid prefix, calling super.validateMessage again with an extended version of SaajSoapMessage that overloads the getDocument() method with a new implementation that removes the unwanted prefix before returning the document.
@Override
protected void validateMessage(SoapMessage soapMessage, MessageContext messageContext) throws WsSecurityValidationException {
try {
super.validateMessage(soapMessage, messageContext);
} catch (WsSecurityValidationException e) {
if (!hasInvalidPrefix((SaajSoapMessage) soapMessage)) {
throw e;
}
log.info("Default signature validation failed, adjusting message by removing the prefix and reattempting signature validation");
DefaultNamespaceAdjustedSaajSoapMessage customSaajSoapMessage = new DefaultNamespaceAdjustedSaajSoapMessage(((SaajSoapMessage) soapMessage).getSaajMessage());
super.validateMessage(customSaajSoapMessage, messageContext);
}
}
@Override
public Document getDocument() {
Document document = super.getDocument();
try {
(((SOAPPart) document).getEnvelope()).getBody().setPrefix(null);
} catch (SOAPException e) {
throw new RuntimeException(e);
}
return document;
}
My question is this:
Is this a bug, and if so should it be reported to spring-ws or spring-security?
If it isn't a bug is there a better way to solve this, perhaps by somehow configuring whether the default namespace prefix should be added or not?
An example message
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
<testOk xmlns="http://testing.se/TestOk">
<hello>This is a testOk test message</hello>
</testOk>
</Body>
</Envelope>
Unfortunately, I was unable to add the signed version of the message, as doing so led to my question being flagged as spam and I was not allowed to post it.