使用Wireshark 嗅探器,我截获了您的 PHP 代码发送的 SOAP 请求。它看起来像这样:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="urn:examples:helloservice"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns2="urn:localhost-catalog"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Header>
<ns2:UsernameToken>
<Password>pass</Password>
<Username>login</Username>
</ns2:UsernameToken>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:getProductGroups>
<parentId>1</parentId>
</ns1:getProductGroups>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
在这里您可以看到此代码为 UsernameToken 标头添加了 ns2 命名空间。
然后我截获了发送 Ruby 代码的 SOAP 请求:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wsdl="http://www.ecerami.com/wsdl/HelloService.wsdl"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-1"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>usr</wsse:Username>
<wsse:Password
Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">
pass
</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</env:Header>
<env:Body>
<wsdl:getProductGroups>
<parentId>1</parentId>
</wsdl:getProductGroups>
</env:Body>
</env:Envelope>
您可以看到差异 - UsernameToken 被包装到 Security 元素中,并且 UsernameToken 的命名空间是“http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”
您的 PHP 代码使用自定义授权,而 savon 不通过 wsse 属性支持它。我查看了 Savon 源代码,它使用 Akami.wsse,并且在其代码中无法设置命名空间。这意味着您需要手动构建标题。这是 Ruby 中的代码,它可以生成您可能需要的 SOAP 请求:
require 'savon'
client = Savon::Client.new do
wsdl.document = "test.wsdl"
end
client.request :wsdl, "sayHello" do
soap.namespaces["xmlns:ns2"] = "urn:localhost-catalog"
soap.header = { "ns2:UsernameToken" =>
{"Password" => "pass", "Username" => "login"}
}
soap.body = { :parent_id => 1 }
end
它生成以下 SOAP 请求:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wsdl="http://www.ecerami.com/wsdl/HelloService.wsdl"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns2="urn:localhost-catalog">
<env:Header>
<ns2:UsernameToken>
<Password>pass</Password>
<Username>login</Username>
</ns2:UsernameToken>
</env:Header>
<env:Body>
<wsdl:sayHello>
<parentId>1</parentId>
</wsdl:sayHello>
</env:Body>
</env:Envelope>
希望这可以帮助!