azure-api-management

APIM Policy - Fetch value from incoming SOAP requset and set variable


I have this SOAP request incoming in my API:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://example.com/webservice">
   <soapenv:Header>
      <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
         <wsse:UsernameToken>
            <wsse:Username>myUsername</wsse:Username>
            <wsse:Password>myPassword</wsse:Password>
         </wsse:UsernameToken>
      </wsse:Security>
   </soapenv:Header>
   <soapenv:Body>
      <web:YourRequest>
      </web:YourRequest>
   </soapenv:Body>
</soapenv:Envelope>

My requirement is to fetch "Username" and set it as a variable.

So far, I have tried:

Converting the incoming request to JSON:

<xml-to-json kind="javascript-friendly" apply="always" consider-accept-header="true" />

Then set variable:

<set-variable name="jsonBody" value="@(context.Response.Body.As<JObject>(preserveContent: true))"/>
<set-variable name="age" value="@((string)((JObject)context.Variables[" jsonBody"])["soapenv$Envelope"]["soapenv$Header"]["wsse$Security"]["wsse$UsernameToken"]["wsse$Username"]["$t"])"/>

But it gives me error:

set-variable (0.243 ms)
{
    "messages": [
        {
            "message": "Expression evaluation failed.",
            "expression": "context.Response.Body.As<JObject>(preserveContent: true)",
            "details": "Object reference not set to an instance of an object."
        },
        "Expression evaluation failed. Object reference not set to an instance of an object.",
        "Object reference not set to an instance of an object."
    ]
}

I don't necessarily have to convert the incoming request to JSON but I'm more comfortable with JSON so I did. Can someone please help me correct the policy?


Solution

  • You need to modify the policy as given below to get the expected response.

    <policies>
        <inbound>
            <base />
            <xml-to-json kind="javascript-friendly" apply="always" consider-accept-header="true" />
            <set-variable name="jsonBody" value="@(context.Request.Body.As<JObject>(preserveContent: true))" />
            <set-variable name="username" value="@((string)((JObject)context.Variables["jsonBody"])["soapenv$Envelope"]["soapenv$Header"]["wsse$Security"]["wsse$UsernameToken"]["wsse$Username"]["$t"])" />
            <return-response>
                <set-status code="200" reason="OK" />
                <set-header name="Content-Type" exists-action="override">
                    <value>application/json</value>
                </set-header>
                <set-body>@("{ 'Username is': '" + context.Variables["username"] + "' }")</set-body>
            </return-response>
        </inbound>
        <backend>
            <base />
        </backend>
        <outbound>
            <base />
        </outbound>
        <on-error>
            <base />
        </on-error>
    </policies>
    

    You will get the below response.

    enter image description here

    enter image description here