SOAP Message Validator -Does it validates SOAP Header Namespace

Hi,

I have two name space one in SOAP Header and another with SOAP Method as below.

Looks like SOAP Message Validator Policy only validates the SOAP Method Namespace, but if I change the namespace inside the SOAP Header, it does not validate, if I indicate it to validate from SOAP Validator Policy as below .

My SOAPMessage Validator Policy looks like below.

<MessageValidation async="false" continueOnError="false" enabled="true"
                   name="SOAP-Message-Validation">
  <DisplayName>SOAP Message Validation</DisplayName>
  <Properties/>
  <Element namespace="MethodNamespace">SoapMethodName</Element>
  <Element namespace="HeaderNamespace">SOAPHeaderTag</Element>
  <SOAPMessage/>
  <Source>request</Source>
  <ResourceURL>wsdl://MySOAP.wsdl</ResourceURL>
</MessageValidation>

1.If My request is as below, where I have given correct Header and Body namespace

<soap12:Envelope xmlns:xsi=NameeeeeSpacceeee" xmlns:soap12="AnotherValue">
  <soap12:Header>
    <AuthSOAPHeader xmlns="HeaderNamespace">
      <MoreHeaderElementsHere/>
    </AuthSOAPHeader>
  </soap12:Header>
  <soap12:Body>
    <SoapMethodName xmlns="MethodNamespace">
      <Other ElementsofBODY='foo'/>
    </SoapMethodName>
  </soap12:Body>
</soap12:Envelope>

2. If I change the SoapMethodName element to below,

<SoapMethodName xmlns="MethodNames"> <!-- instead of "MethodNamespace" -->

it gives me following error

{"fault":{"faultstring":"SOAP-Message-Validation failed with reason: \"Unexpected Root Element SoapMethodName [Line xx]\"","detail":{"errorcode":"steps.messagevalidation.Failed"}}}

3. If I change, in the request

<AuthSOAPHeader xmlns="HeaderNamespace">

to

<AuthSOAPHeader xmlns="Header">

...the policy does not complain, it just passes without complaining about MISMATCH in Header namespace.

I have indicated in SOAP MessageValidator to validate both Body name space and Header namespace, but not sure only Body name space is detected but not Header namespace.

Let me know, if I need to change the validation Policy information or may be need to update any other way or such header namespace validation is not possible ?

1 6 5,197
6 REPLIES 6

The behavior you observed regarding the validation of Header elements... is as the policy has been implemented.

I apologize. First, the documentation for the MessageValidation policy is not adequate. It does not describe the behavior of the policy effectively. There are not enough examples explaining how it works and how to accomplish basic, typical tasks.

Also, I think the policy ought to be able to validate the elements within the SOAP Header, when you specify a WSDL. According to your report, It currently does not have that capability. (I did not test this specifically, since I don't have your WSDL.)

One way to accomplish what you want is to validate against a specific XSD for your soap message, rather than using the WSDL. The policy configuration looks like this:

<MessageValidation name="MV-XSD-1">
  <Source>request</Source>
  <ResourceURL>xsd://example.xsd</ResourceURL>
</MessageValidation>

Whoa! There's no

<Element namespace="MethodNamespace">SoapMethodName</Element>

...in there. How could it possibly do what you want? Well, the reason is the XSD is a strict specification of the message, including the element name and namespace URI for the SOAP Method, and including the element name and namespace for the SOAP Header. If any of those things in the actual message don't comply with the XSD, then the MessageValidator will throw an error, as expected and desired.

What is the XSD for this soap message? I used this:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           targetNamespace="http://www.w3.org/2003/05/soap-envelope"
           xmlns:header="urn://HeaderNamespace"
           xmlns:body="urn://MethodNamespace"
           xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <xs:import namespace="urn://HeaderNamespace" schemaLocation="xsd://header-child.xsd"/>
  <xs:import namespace="urn://MethodNamespace" schemaLocation="xsd://body-child.xsd"/>
  <xs:element name="Envelope">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="soap12:Header"/>
        <xs:element ref="soap12:Body"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="Header">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="header:AuthSOAPHeader"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="Body">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="body:SoapMethodName"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

...which I obtained through the help of this online XSD inference tool, passing in this XML:

<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                 xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Header>
    <AuthSOAPHeader xmlns="urn://HeaderNamespace">
      <MoreHeaderElementsHere/>
    </AuthSOAPHeader>
  </soap12:Header>
  <soap12:Body>
    <SoapMethodName xmlns="urn://MethodNamespace">
      <Other ElementsofBODY='foo'/>
    </SoapMethodName>
  </soap12:Body>
</soap12:Envelope>

Attached please find an example api proxy that demonstrates the technique. There is a README explaining how to use it.

soap-validator.zip


ps: you may be able to get the WSDL-based header validation to work if you include this:

   <SOAPMessage version='1.2'/>

In your policy config you did not specify the SOAP version. Also eliminate the <Element> . You should not need that if your WSDL is strict enough. I haven't tested this.

FYI, I updated the SOAP Message Validation Policy documentation to include examples that validate XSD and SOAP, and check JSON and XML for well-formedness.

Hello, following up on this thread. Does this mean the SOAP Message Validator policy does not validate the SOAP Header by design? It just validates the SOAP body?

If you're right, and this is by design, then this is a bad design which should be qualified as a bug and fixed.

Dave, yes that was my understanding when I looked at this in December 2017. And also I think Yuriy's viewpoint is valid.

We did find a workaround for this, which was very close to what Dino posted.

We used a very similar XSD, but we based it closer to the SOAP envelope XSD file into the proxy, which is available at http://www.w3.org/2003/05/soap-envelope. Referencing that in the MessageValidation policy, that will validate the header. Only specify the source and resourceURL.

In the XSD, it references the header XSD and the body XSD.

<MessageValidation name="MV-XSD-1">
  <Source>request</Source>
  <ResourceURL>xsd://soap-envelope.xsd</ResourceURL>
</MessageValidation>
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
            xmlns:tns="http://schemas.xmlsoap.org/soap/envelope/"
            xmlns:header="http://company.com/MessageHeader"
            xmlns:body="http://company.com/body.xsd"
            elementFormDefault="qualified"
            targetNamespace="http://schemas.xmlsoap.org/soap/envelope/">
   <xs:import namespace="http://company.com/MessageHeader"
               schemaLocation="xsd://Header.xsd"/>
   <xs:import namespace="http://company.com/body.xsd"
               schemaLocation="xsd://body.xsd"/>


  <!-- Envelope, header and body -->
  <xs:element name="Envelope" type="tns:Envelope" />
  <xs:complexType name="Envelope" >
    <xs:sequence>
      <xs:element ref="tns:Header" minOccurs="1" />
      <xs:element ref="tns:Body" minOccurs="1" />
      <xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
    </xs:sequence>
    <xs:anyAttribute namespace="##other" processContents="lax" />
  </xs:complexType>


  <xs:element name="Header" type="tns:Header" />
  <xs:complexType name="Header" >
    <xs:sequence>
      <xs:element ref="header:MessageHeader"/>
      <!-- <xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="lax" /> -->
    </xs:sequence>
    <xs:anyAttribute namespace="##other" processContents="lax" />
  </xs:complexType>
  
  <xs:element name="Body" type="tns:Body" />
  <xs:complexType name="Body" >
    <xs:sequence>
      <xs:element ref="body:MessageBody"/>
      <!-- <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" /> -->
    </xs:sequence>
    <xs:anyAttribute namespace="##any" processContents="lax" >
     <xs:annotation>
       <xs:documentation>
        Prose in the spec does not specify that attributes are allowed on the Body element
      </xs:documentation>
     </xs:annotation>
   </xs:anyAttribute>
  </xs:complexType>


       
  <!-- Global Attributes.  The following attributes are intended to be usable via qualified attribute names on any complex type referencing them.  -->
  <xs:attribute name="mustUnderstand" >   
     <xs:simpleType>
     <xs:restriction base='xs:boolean'>
      <xs:pattern value='0|1' />
    </xs:restriction>
   </xs:simpleType>
  </xs:attribute>
  <xs:attribute name="actor" type="xs:anyURI" />


  <xs:simpleType name="encodingStyle" >
    <xs:annotation>
     <xs:documentation>
       'encodingStyle' indicates any canonicalization conventions followed in the contents of the containing element.  For example, the value 'http://schemas.xmlsoap.org/soap/encoding/' indicates the pattern described in SOAP specification
     </xs:documentation>
   </xs:annotation>
    <xs:list itemType="xs:anyURI" />
  </xs:simpleType>


  <xs:attribute name="encodingStyle" type="tns:encodingStyle" />
  <xs:attributeGroup name="encodingStyle" >
    <xs:attribute ref="tns:encodingStyle" />
  </xs:attributeGroup>


  <xs:element name="Fault" type="tns:Fault" />
  <xs:complexType name="Fault" final="extension" >
    <xs:annotation>
     <xs:documentation>
       Fault reporting structure
     </xs:documentation>
   </xs:annotation>
    <xs:sequence>
      <xs:element name="faultcode" type="xs:QName" />
      <xs:element name="faultstring" type="xs:string" />
      <xs:element name="faultactor" type="xs:anyURI" minOccurs="0" />
      <xs:element name="detail" type="tns:detail" minOccurs="0" />      
    </xs:sequence>
  </xs:complexType>


  <xs:complexType name="detail">
    <xs:sequence>
      <xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
    </xs:sequence>
    <xs:anyAttribute namespace="##any" processContents="lax" /> 
  </xs:complexType>


</xs:schema>