如何设置 header 在 mulesoft 中调用 soap 服务

How to set header to call soap service in mulesoft

我想通过 mulesoft 调用一个 soap 服务。 为了将 header 附加到 soap 请求 body,我使用了这些 links -Mule 3.7. Add custom SOAP header to web-service-consumer。如本 link 中所述,我在 "Web Service Consumer" 之前添加了 "Message Properties" 组件,但我遇到了以下异常 -

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

我也尝试使用 属性 组件,如此处所述 - https://dzone.com/articles/working-with-headers-in-mule-flows

我仍然无法访问 soap 服务。有没有其他方法可以将 header 添加到 soap 请求 body 中? Header 我想添加到我的 soap 请求中 -

<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>

--更新-我的代码-

    <?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>

---更新---

答案实际上分为两个部分,对于如何添加 SOAP header 的直接问题,看起来您可能错过了为安全元素声明 soapenv 的命名空间添加。例如,下面的代码应该可以将 "Security" header 添加到 SOAP 信封。必须定义整个 XML 元素,包括它使用的任何命名空间。

<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"/>

虽然这看起来很不吸引人,但由于您要添加 username/password 安全性 header 那么您可能希望将其直接添加到 Web 服务消费者配置本身的安全性元素中:

<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>

上面的问题是它不会添加 soapenv:actor="appId" 属性。

看起来 WS 消费者的安全配置将覆盖 actor 属性。下面的代码主要适用于 Mule 3.8 并使用此处找到的示例 WSDL:https://github.com/skjolber/mockito-soap-cxf/tree/master/src/test/resources/wsdl

第一个流程构建对 SOAP Web 服务的请求,第二个流程仅接收第一个流程发出的请求并将其记录下来。

<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>

运行 对 localhost:8092 的简单 GET 请求创建静态 Web 服务请求并通过 WS 消费者组件将其发送到。存根中的记录器打印出整个 SOAP 信封,如下所示,其中包括安全性 header,但不包括 actor 属性:

<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>

我会做更多的研究,看看我是否可以在安全性中包含 actor 属性 header。因为这是一个标准属性,所以应该是可能的。我会尽可能更新这个答案。

约翰逊。