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


Allowing Attributes in SoapVar / SoapHeader Without a Type Definition or Namespace

我得到了一个不包含任何soap报头模式或定义的WSDL,但是端点需要一个wse类型的报头。我使用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头(如果可能的话),或者是否有另一种逻辑方法为这个名称空间/XSD模式生成正确的SOAP头?

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

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

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