在没有类型定义或命名空间的情况下允许SoapVar / SoapHeader中的属性

时间:2016-09-29 13:37:24

标签: php xml soap wsdl soap-client

我已经获得了一个不包含任何soap头模式或定义的WSDL,但是端点需要一个WSSE类型的头。我使用SoapClient来处理这些请求。

所有请求必须在其标题中包含此内容:

<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    <wsse:UsernameToken>
        <wsse:Username>Username</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>

如果我在StackOverflow和在线PHP文档评论中多次建议路线,那么我能得到的最接近的是:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="..." xmlns:ns2="..." xmlns:ns3="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
    <SOAP-ENV:Header>
        <ns3:Security>
            <ns3:UsernameToken>
                <ns3:Username>Username</ns3:Username>
                <ns3:Password>Password</ns3:Password>
            </ns3:UsernameToken>
        </ns3:Security>
 ...

注意它如何将名称空间添加到soap信封中,而给定的规范/示例将名称空间专门添加到Security元素。但我不认为这很重要。无论哪种方式,Password元素都缺少它的type属性。 我还尝试使用以下方式沿着阵列路线走下去:

$securityNamespace = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';

// ...

$password = new \SoapVar(
    [
        '_' => 'Password',
        'type' => 'http://...'
    ],
    SOAP_ENC_OBJECT,
    null,
    $securityNamespace,
    null,
    $securityNamespace
);

生成为:

<value>
    <item>
        <key>_</key>
        <value>PASSWORD</value>
    </item>
    <item>
        <key>type</key>
        <value>http://...</value>
    </item>
</value>

当SoapClient无法找到要验证的元素类型时,这显然是一种典型的响应。

WSDL和随附的XSD在本地保存用于缓存目的,是否值得尝试修改WSDL以包含WSSE头(如果可能的话),或者是否有另一种逻辑方法来生成正确的SOAP此命名空间/ XSD架构的标头?

1 个答案:

答案 0 :(得分:0)

https://github.com/goetas-webservices/soap-client完全是PHP SOAP客户端,不依赖于PHP的ext-soap

它已经支持PSR7,多客户端,并允许通过IDE为类型提示生成类。

https://github.com/goetas-webservices/soap-client-demo是一个演示项目,它允许您了解如何使用客户端来使用通用的SOAP Web服务。