Loading…
Loading…
Describes the mechanism for extracting a service identity ({namespace}LocalName) from a SOAP request body or bare XML payload for service attribution.
The SoapBodyIdentity component parses an XML request payload to extract a unique service identifier. This identifier consists of the XML namespace and local name of a specific element within the payload.
This component solves the problem of identifying a target service when the request URL is insufficient for routing, which is a common scenario for SOAP-based APIs. For most document/literal-wrapped SOAP services, the first child element of the SOAP <Body> corresponds directly to the WSDL operation name. SoapBodyIdentity extracts this element's identity, enabling precise service attribution on the API platform's ingest path.
The parser is designed to run on the high-performance ingest path and handles untrusted traffic from API consumers. It is hardened against XML External Entity (XXE) and other XML-based attacks.
The primary input is the raw request body as a string. The output is a SoapBodyIdentity object containing the namespace and localName of the identifying element, or null if an identity cannot be determined.
The SoapBodyIdentity.parse() method implements a multi-stage process to safely and efficiently extract the service identity from a raw payload.
flowchart TD
subgraph "SoapBodyIdentity.parse()"
A[Start: Receive string payload] --> B{Payload is null or blank?};
B -- Yes --> Z[Return null];
B -- No --> C[Truncate payload to 256 KB];
C --> D{Payload contains '<' character?};
D -- No --> Z;
D -- Yes --> E[Parse XML with security features];
E -- Parse Fails --> Z;
E -- Parse Succeeds --> F[Get root element];
F --> G{Is root a SOAP Envelope?};
G -- Yes --> H[Find first element child of <Body>];
G -- No --> I[Use root element as identity];
H --> J{Element found?};
J -- No --> Z;
J -- Yes --> K[Identity Element];
I --> K;
K --> L{Element has local name?};
L -- No --> Z;
L -- Yes --> M[Extract namespace and local name];
M --> N[Return SoapBodyIdentity object];
endThe process follows these steps:
Initial Validation: The method first checks if the input payload string is null or blank. If it is, processing stops and returns null.
Payload Truncation: To optimize performance and limit memory usage, the payload is truncated to the first 256 KB (MAX_PARSE_CHARS). The service identity is expected to be at the beginning of the document.
Pre-Parse Check: Before attempting to start a full XML parser, the method performs a fast check for the presence of a < character. If none is found, it assumes the payload is not XML (e.g., it might be JSON or an opaque binary stream) and returns null. This "cheap reject" avoids unnecessary processing on the ingest hot path.
Secure XML Parsing: If the payload appears to be XML, a namespace-aware DocumentBuilder is configured with strict security features to protect against vulnerabilities when processing untrusted input. These features include:
NOTE
The parser uses a custom error handler (IngestXmlErrorHandler.INSTANCE) that suppresses output for expected parsing failures. Because this component processes all types of traffic on the ingest path, many payloads are not valid XML. Without this handler, the system logs would be flooded with benign error messages. A failure to parse is treated as a valid outcome, resulting in a null identity.
Identity Element Discovery:
Envelope. This check is case-insensitive for the tag name "Envelope" and recognizes SOAP 1.1 (http://schemas.xmlsoap.org/soap/envelope/), SOAP 1.2 (http://www.w3.org/2003/05/soap-envelope), and even envelopes with no namespace declared.<Body> tag and identifies its first child element, skipping any whitespace or comment nodes. This child element is considered the identity element.Identity Extraction:
localName, and falling back to manually stripping the prefix from the tagName if necessary.getNamespaceURI(). If the namespace is null, it is treated as an empty string.Return Value: If all steps succeed, a SoapBodyIdentity object containing the namespace and localName is returned. If any step fails (e.g., parse error, no identity element found), the method returns null.
SoapBodyIdentity.parse(String payload)Parses a string payload to find the service-identifying element.
| Parameter | Type | Description |
|---|---|---|
payload | String | The request body payload to parse. Can be a full SOAP envelope or a bare XML document. The parser only reads up to the first 256 KB. May be null or empty. |
Returns
SoapBodyIdentity object on success.null if the payload is empty, not valid XML, or if a service-identifying element cannot be found.SoapBodyIdentity Return TypeThe SoapBodyIdentity object is a record that contains the extracted identity.
| Field | Type | Description |
|---|---|---|
namespace | String | The XML namespace URI of the identifying element. An empty string ("") if the element has no namespace. |
localName | String | The local name of the identifying element (tag name without any namespace prefix). |
| Parameter | Value | Description |
|---|---|---|
MAX_PARSE_CHARS | 262144 | The maximum number of characters (256 * 1024) from the start of the payload that will be considered for parsing. Payloads larger than this are truncated before parsing. |
The parse method will return null instead of a SoapBodyIdentity object under several conditions. This is the expected behavior when a definitive identity cannot be extracted.
null, empty, or contains only whitespace.< character, suggesting it is not XML (e.g., JSON).<Body> element, or the <Body> element contains no child elements (e.g., it is empty).SoapServiceAttributionResolver, which uses the extracted identity to route requests.SoapPayloadExtractor.