0

I want to call one soap service through mulesoft. To attach header to soap request body I used these links -Mule 3.7. Add custom SOAP header to web-service-consumer. As mentioned in this link, I have added "Message Properties" component before "Web Service Consumer", but I am getting below exception -

com.ctc.wstx.exc.WstxParsingException: Undeclared namespace prefix "soapenv" (for attribute "actor")

Also I tried it using Property component as mentioned here - https://dzone.com/articles/working-with-headers-in-mule-flows

Still I am not able to hit soap service. Is there any other way to add header to soap request body? Header that i want to add to my soap request -

<wsse:Security soapenv:actor="AppID" soapenv:mustUnderstand="1"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
    <wsse:Username>Pilot\ABCD</wsse:Username>
    <wsse:Password wsse:Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">yt15#58</wsse:Password>
</wsse:UsernameToken>

--Update- My code-

    <?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:dw="http://www.mulesoft.org/schema/mule/ee/dw" xmlns:ws="http://www.mulesoft.org/schema/mule/ws" xmlns:metadata="http://www.mulesoft.org/schema/mule/metadata" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xmlns:spring="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/ws http://www.mulesoft.org/schema/mule/ws/current/mule-ws.xsd
http://www.mulesoft.org/schema/mule/ee/dw http://www.mulesoft.org/schema/mule/ee/dw/current/dw.xsd">
     <ws:consumer-config name="Web_Service_Consumer_2" wsdlLocation="https://soa.abc.com/abcd_v4_0?wsdl" service="abcdService_vs0" port="xyz_Internal" serviceAddress=""https://soa.abc.com:56655/abcd_v4_0" doc:name="Web Service Consumer">
        <ws:security>
            <ws:wss-username-token username="user" password="password" passwordType="TEXT"/>
        </ws:security>
    </ws:consumer-config>
    <sub-flow name="tempSub_Flow">
        <set-property propertyName="soap.Security" value="&lt;wsse:Security soapenv:actor=&quot;AppID&quot; soapenv:mustUnderstand=&quot;1&quot; xmlns:wsse=&quot;http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd&quot; xmlns:soapenv=&quot;http://schemas.xmlsoap.org/soap/envelope/&gt;&lt;/wsse:Security&gt;" doc:name="Property"/>
        <dw:transform-message doc:name="Transform Message">
            <dw:set-payload><![CDATA[%dw 1.0
%output application/xml
%namespace ns0 urn:abc.com:schemas:gfr:a:b:service:2014-01-10
---
{
    ns0#addTransaction:{
        ns0#aTransaction: {
            ns0#transactionCode: "xyz",
            ns0#methodCode: "abc",
            ns0#amount: flowVars.amount,
            ns0#effectiveDate:  now as :string {format: "yyyy-MM-dd"}   

        }
    } 
}]]></dw:set-payload>
        </dw:transform-message>
        <ws:consumer config-ref="Web_Service_Consumer_2" operation="addEftTransaction" doc:name="Web Service Consumer"/>
        <dw:transform-message doc:name="Transform Message">
            <dw:set-payload><![CDATA[%dw 1.0
%output application/java
%namespace ns0 urn:abc.com:schemas:gfr:a:b:service:2014-01-10
---

payload.ns0#addTransactionResponse.ns0#transactionNumber
]]></dw:set-payload>
        </dw:transform-message>
    </sub-flow>
</mule>
Nitesh
  • 1,477
  • 5
  • 23
  • 34

1 Answers1

1

--- UPDATE ---

Two parts to the answer really, for the direct question of how to add SOAP headers, it looks like you might have missed declaring the namespace of soapenv for the Security element you were adding. For example, the below code should work for adding the "Security" header to the SOAP Envelope. The whole XML element must be defined, including any namespaces it uses.

<set-property propertyName="soap.Security" value="&lt;wsse:Security soapenv:actor=&quot;AppID&quot; soapenv:mustUnderstand=&quot;1&quot; xmlns:wsse=&quot;http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd&quot; xmlns:soapenv=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;&gt;&lt;wsse:UsernameToken&gt;&lt;wsse:Username&gt;Pilot\ABCD&lt;/wsse:Username&gt;&lt;wsse:Password wsse:Type=&quot;http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText&quot;&gt;yt15#58&lt;/wsse:Password&gt;&lt;/wsse:UsernameToken&gt;&lt;/wsse:Security&gt;" doc:name="Set soap.Security"/>

That looks pretty unattractive though, and since you are adding a username/password security header then you probably want to add this directly into the security element of the Web Service Consumer configuration itself:

<ws:consumer-config name="WSConfig" wsdlLocation="MyService.wsdl" service="MyService" port="MyPort" serviceAddress="https://example.com" doc:name="Web Service Consumer">
    <ws:security>
        <ws:wss-username-token username="Pilot\ABCD" password="yt15#58" passwordType="TEXT"/>
    </ws:security>
</ws:consumer-config>

The issue with the above is that it won't add the soapenv:actor="appId" attribute.

It looks like the security configuration on the WS consumer will overwrite the actor attribute. The below code mostly works on Mule 3.8 and uses the sample WSDL found here: https://github.com/skjolber/mockito-soap-cxf/tree/master/src/test/resources/wsdl

The first flow builds the request to the SOAP web service, the second flow just receives the request made by the first flow and logs it.

<mule xmlns:metadata="http://www.mulesoft.org/schema/mule/metadata" 
    xmlns:dw="http://www.mulesoft.org/schema/mule/ee/dw" 
    xmlns:ws="http://www.mulesoft.org/schema/mule/ws" 
    xmlns:http="http://www.mulesoft.org/schema/mule/http" 
    xmlns="http://www.mulesoft.org/schema/mule/core" 
    xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" 
    xmlns:spring="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/ws http://www.mulesoft.org/schema/mule/ws/current/mule-ws.xsd
http://www.mulesoft.org/schema/mule/ee/dw http://www.mulesoft.org/schema/mule/ee/dw/current/dw.xsd">
    <ws:consumer-config name="BankCustomerService_WS_Consumer" wsdlLocation="BankCustomerService.wsdl" service="BankCustomerService" port="BankCustomerServicePort" serviceAddress="http://localhost:8778/services/bankCustomer" doc:name="Web Service Consumer">
        <ws:security>
            <ws:wss-username-token username="user" password="password" passwordType="TEXT"/>
        </ws:security>
    </ws:consumer-config>
    <http:listener-config name="HTTP_TestListener" host="0.0.0.0" port="8092" doc:name="HTTP Listener Configuration"/>
    <http:listener-config name="HTTP_WebServiceStub" host="0.0.0.0" port="8778" doc:name="HTTP Listener Configuration"/>
    <flow name="soapsandboxFlow">
        <http:listener config-ref="HTTP_TestListener" path="/soap" doc:name="HTTP"/>
        <set-property propertyName="soap.Security" value="&lt;wsse:Security soapenv:actor=&quot;AppID&quot; xmlns:wsse=&quot;http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd&quot; xmlns:soapenv=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot; /&gt;" doc:name="Set soap.Security"/>
        <dw:transform-message doc:name="Transform Message">
            <dw:set-payload><![CDATA[%dw 1.0
%output application/xml
%namespace ns0 http://example.bank.skjolber.github.com/v1
---
{
    ns0#getAccountsRequest: {
        ns0#customerNumber: 987654321,
        ns0#certificate: 1234
    }
}]]></dw:set-payload>
        </dw:transform-message>
        <ws:consumer config-ref="BankCustomerService_WS_Consumer" operation="getAccounts" doc:name="Web Service Consumer"/>
    </flow>
    <flow name="soapsandboxFlow1">
        <http:listener config-ref="HTTP_WebServiceStub" path="services/bankCustomer" doc:name="HTTP"/>
        <logger message="#[message.payloadAs(String)]" level="INFO" doc:name="Logger"/>
    </flow>
</mule>

Running a simple GET request to localhost:8092 creates a static web service request and sends that to through the WS Consumer Component. The logger in the stub prints out the entire SOAP envelope, which as shown below includes the security header, but not the actor attribute:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header>
        <wsse:Security xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
            xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" 
            xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soapenv:mustUnderstand="1">
            <wsse:UsernameToken wsu:Id="UsernameToken-CA524029E5DEDE6E3715320371056746">
                <wsse:Username>user</wsse:Username>
                <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
            </wsse:UsernameToken>
        </wsse:Security>
    </soap:Header>
    <soap:Body>
        <ns0:getAccountsRequest xmlns:ns0="http://example.bank.skjolber.github.com/v1">
            <ns0:customerNumber>987654321</ns0:customerNumber>
            <ns0:certificate>1234</ns0:certificate>
        </ns0:getAccountsRequest>
    </soap:Body>
</soap:Envelope>

I will do a bit more research to see if I can include the actor attribute in the security header. As this is a standard attribute I it should be possible. I will update this answer when I can.

Johnson.

Johnson
  • 451
  • 2
  • 13
  • Thank you @Johnson for looking into it. I tried both options. But it was not working. Then I tried first option to add header using "Property" Component. But it was giving error - **org.apache.cxf.binding.soap.SoapFault: Authentication error: Cannot find WS-Security header**. I have used your code from option first. To resolve the issue I have added **** tag before ** – Nitesh Jul 19 '18 at 10:01
  • Hi @Nitesh, I can't reproduce the errors you are seeing - what version of Mule are you running? Would you be able to share your code? I have updated my answer with an almost working flow, this is dropping the actor attribute on the security header though, I'm looking into why this is. – Johnson Jul 19 '18 at 21:57
  • Thank you @Johnson. I really appreciate your help. I am using Mule 3.9.0 – Nitesh Jul 20 '18 at 08:50
  • I have added my code in update section. Please let me know if you want more information. Thank you so much! – Nitesh Jul 20 '18 at 10:45
  • The problem is with Actor. I have added two properties and it worked for me. Now I am able to hit that service. Thank you so much Johnson for your valuable time.. – Nitesh Jul 20 '18 at 13:59
  • I have added to Property Component - ** ** – Nitesh Jul 20 '18 at 14:00