1. The code where the body element is marked as an id and the signature is verified.

    This approach should only be preferred if it is known that the signature's reference is the body.

import org.apache.xml.security.signature.XMLSignature;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
 
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.security.cert.X509Certificate;
 
 
if (credential_certificate== null) {
    requestErrorMessageToTargetAPI="Client certificate not found.";
    statusCodeToTargetAPI=400;
    return;
}
 
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder builder = dbf.newDocumentBuilder();
Document doc = builder.parse(new ByteArrayInputStream(requestBodyTextFromClient.getBytes()));
 
// Find the <soap:Body> element
NodeList bodyNodes = doc.getElementsByTagNameNS("http://schemas.xmlsoap.org/soap/envelope/", "Body");
if (bodyNodes.getLength() > 0) {
    Element bodyElement = (Element) bodyNodes.item(0);
    // Set wsu:Id attribute to ID
    bodyElement.setIdAttributeNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "Id", true);
}
 
NodeList nl = doc.getElementsByTagNameNS(javax.xml.crypto.dsig.XMLSignature.XMLNS, "Signature");
if (nl.getLength() == 0) {
    requestErrorMessageToTargetAPI="Signature not found.";
    statusCodeToTargetAPI=400;
    return;
}
 
// Load XMLSignature from document
XMLSignature signature = new XMLSignature((Element) nl.item(0), doc.getDocumentURI());
  
  
boolean isValid = signature.checkSignatureValue(credential_certificate);
if (isValid) {
   requestHeaderMapToTargetAPI.put("isValid",isValid);
} else {
    requestErrorMessageToTargetAPI="Signature not valid. ";
    statusCodeToTargetAPI=401;
    return;
} 
GROOVY

2. The code where all elements with an id attribute value are marked as ids and the signature is verified.

    This approach should be preferred in cases where the reference(s) of the signature are unknown, and when the XML size is relatively small. (Because searching is done in all elements).

import org.apache.xml.security.signature.XMLSignature;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
 
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.security.cert.X509Certificate;
 
if (credential_certificate== null) {
    requestErrorMessageToTargetAPI="Client certificate not found.";
    statusCodeToTargetAPI=400;
    return;
}
 
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder builder = dbf.newDocumentBuilder();
Document doc = builder.parse(new ByteArrayInputStream(requestBodyTextFromClient.getBytes()));
 
 
NodeList nl = doc.getElementsByTagNameNS(javax.xml.crypto.dsig.XMLSignature.XMLNS, "Signature");
if (nl.getLength() == 0) {
    requestErrorMessageToTargetAPI="Signature not found.";
    statusCodeToTargetAPI=400;
    return;
}
 
// Save elements with ID as ID correctly
NodeList allElements = doc.getElementsByTagName("*");
for (int i = 0; i < allElements.getLength(); i++) {
    Element element = (Element) allElements.item(i);
    if (element.hasAttribute("wsu:Id")) {
        element.setIdAttribute("wsu:Id", true); // Mark element as ID in DOM
    }
}
 
//Load XMLSignature from document
XMLSignature signature = new XMLSignature((Element) nl.item(0), doc.getDocumentURI());
 
boolean isValid = signature.checkSignatureValue(credential_certificate);
if (isValid) {
   requestHeaderMapToTargetAPI.put("isValid",isValid);
} else {
    requestErrorMessageToTargetAPI="Signature is not valid.";
    statusCodeToTargetAPI=401;
    return;
}
GROOVY

3. The code where elements with the referenced id inside the signature element are located using XPath and marked as ids, and the signature is verified.

    This approach should be preferred in cases where the reference(s) of the signature are unknown and when the XML size is relatively large. (Because instead of searching in all elements, only elements with the specified id are marked using XPath).

package xml;
 
import com.apinizer.common.util.SimpleNamespaceContext;
import org.apache.xml.security.signature.Reference;
import org.apache.xml.security.signature.XMLSignature;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
 
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import java.io.ByteArrayInputStream;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
  
 
if (credential_certificate== null) {
    requestErrorMessageToTargetAPI="Client certificate not found.";
    statusCodeToTargetAPI=400;
    return;
}
 
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder builder = dbf.newDocumentBuilder();
Document doc = builder.parse(new ByteArrayInputStream(requestBodyTextFromClient.getBytes()));
 
//Find the signature
NodeList nl = doc.getElementsByTagNameNS(javax.xml.crypto.dsig.XMLSignature.XMLNS, "Signature");
if (nl.getLength() == 0) {
    requestErrorMessageToTargetAPI="Signature not found.";
    statusCodeToTargetAPI=400;
    return;
}
 
 
// Install XMLSignature
XMLSignature signature = new XMLSignature((Element) nl.item(0), doc.getDocumentURI());
 
 
//Mark references as id
XPath xpath = XPathFactory.newInstance().newXPath();
Map<String, String> map = new HashMap<>();
map.put("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
SimpleNamespaceContext nsContext = new SimpleNamespaceContext(map);
xpath.setNamespaceContext(nsContext);
 
for (int i = 0; i < signature.getSignedInfo().getLength(); i++) {
    Reference ref = signature.getSignedInfo().item(i);
    String uri = ref.getURI();
    if (uri != null) {
        String id = uri;
        if (id.startsWith("#")) {
            id = id.substring(1);
        }
        String expression = String.format("//*[@wsu:Id='%s']", id);
        Element refElem = (Element) xpath.evaluate(expression, doc, XPathConstants.NODE);
        if (refElem != null) {
            refElem.setIdAttributeNS("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "Id", true);
        }
    }
}
 
 
boolean isValid = signature.checkSignatureValue(credential_certificate);
if (isValid) {
   requestHeaderMapToTargetAPI.put("isValid",isValid);
} else {
    requestErrorMessageToTargetAPI="Signature is not valid.";
    statusCodeToTargetAPI=401;
    return;
}
GROOVY