我正在尝试实施在SAP PI系统上运行的Web服务。我得到的WSDL看起来像这样:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="request_SO" targetNamespace="http://company.ch/orstest/jason_test" xmlns:p1="http://company.ch/orstest/jason_test" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:documentation/>
<wsp:UsingPolicy wsdl:required="true"/>
<wsp:Policy wsu:Id="OP_request_SO"/>
<wsdl:types>
<xsd:schema targetNamespace="http://company.ch/orstest/jason_test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://company.ch/orstest/jason_test">
<xsd:element name="request" type="request"/>
<xsd:element name="response" type="response"/>
<xsd:complexType name="request">
<xsd:annotation>
<xsd:appinfo source="http://sap.com/xi/VersionID">a8b7948ac2e211e2b2380000001f0d6a</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="body" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="response">
<xsd:annotation>
<xsd:appinfo source="http://sap.com/xi/VersionID">bf49af09c36c11e299790000001f0d6a</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="body" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="request">
<wsdl:documentation/>
<wsdl:part name="request" element="p1:request"/>
</wsdl:message>
<wsdl:message name="response">
<wsdl:documentation/>
<wsdl:part name="response" element="p1:response"/>
</wsdl:message>
<wsdl:portType name="request_SO">
<wsdl:documentation/>
<wsdl:operation name="request_SO">
<wsdl:documentation/>
<wsp:Policy>
<wsp:PolicyReference URI="#OP_request_SO"/>
</wsp:Policy>
<wsdl:input message="p1:request"/>
<wsdl:output message="p1:response"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="request_SOBinding" type="p1:request_SO">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/>
<wsdl:operation name="request_SO">
<soap:operation soapAction="http://sap.com/xi/WebService/soap1.1" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/>
<wsdl:input>
<soap:body use="literal" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="request_SOService">
<wsdl:port name="HTTP_Port" binding="p1:request_SOBinding">
<soap:address location="http://qa1100ap601.company.car.web:50000/XISOAPAdapter/MessageServlet?senderParty=&senderService=BS_ORS&receiverParty=&receiverService=&interface=request_SO&interfaceNamespace=http://company.ch/orstest/jason_test" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/>
</wsdl:port>
<wsdl:port name="HTTPS_Port" binding="p1:request_SOBinding">
<soap:address location="https://qas.soa.subcompany.company.ch/XISOAPAdapter/MessageServlet?senderParty=&senderService=BS_ORS&receiverParty=&receiverService=&interface=request_SO&interfaceNamespace=http://company.ch/orstest/jason_test" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
我的PHP文件看起来像这样(目前没有其他内容):
<?php
$client = new SoapClient('test.wsdl');
?>
当我运行我的脚本时,我收到以下错误:
Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Unknown required WSDL extension 'http://schemas.xmlsoap.org/ws/2004/09/policy' in /srv/www/htdocs/wsdl.php:2 Stack trace: #0 /srv/www/htdocs/wsdl.php(2): SoapClient->SoapClient('test.wsdl') #1 {main} thrown in /srv/www/htdocs/wsdl.php on line 2
我尝试在google和StackOverflow上搜索错误,并检查了php.net上的评论,但我似乎无法弄清楚为了让这个服务运行我必须更改的内容。我也尝试打开WSDL扩展URL,它似乎存在。
有人可以在这里给我一块骨头吗?我尝试删除扩展程序网址,导致以下错误:
Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Unexpected WSDL element <UsingPolicy> in /srv/www/htdocs/wsdl.php:2 Stack trace: #0 /srv/www/htdocs/wsdl.php(2): SoapClient->SoapClient('test.wsdl') #1 {main} thrown in /srv/www/htdocs/wsdl.php on line 2
答案 0 :(得分:17)
此时我能想到的唯一解决方案是更新您的UsingPolicy标记:
更改标签:
<wsp:UsingPolicy wsdl:required="true"/>
到此:
<wsp:UsingPolicy wsdl:required="false"/>
答案 1 :(得分:16)
在SAP环境中,这不是正确的答案。在您的WSDL URL中,您将看到/ws_policy/
- 将其更改为/standard/
,您将能够使用PHP SoapClient类来使用Web服务,而无需维护本地修改后的副本WSDL。您可以在SAP博客here上看到相同内容(可能需要登录)。
答案 2 :(得分:5)
的信用对于新版本,网址不再包含“ws_policy” 相反,有一个0(标准)或1(政策)
示例:强>
.... wsdl / flv_10002A1 1 1AD1 / bndg_url / ....(ws_policy)
.... wsdl / flv_10002A1 0 1AD1 / bndg_url / ....(标准)
答案 3 :(得分:0)
似乎是PHP SOAPServer中的一个错误,或者缺少扩展兼容性,至少在PHP 5.6.31中它尚未解决。
我能找到的唯一解决方案是将所需的UsingPolicy
设置为false
,如接受的回复中所示:
<wsp:UsingPolicy wsdl:required="false" />
但客户端无需身份验证即可访问SOAP服务,这是一个严重的安全问题。因此,我尝试手动检查安全数据是否由客户端发送。
$soapEnvelope = new DOMDocument();
$soapEnvelope->loadXML(file_get_contents("php://input"), LIBXML_DTDATTR);
$wsseNamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
if ($soapEnvelope->getElementsByTagNameNS($wsseNamespace, 'Security')->length == 0) {
throw new SoapFault("auth", 'Authentication error - Missing wsse:Security node');
}
if ($soapEnvelope->getElementsByTagNameNS($wsseNamespace, 'UsernameToken')->length == 0) {
throw new SoapFault("auth", 'Authentication error - Missing UsernameToken node');
}
if ($soapEnvelope->getElementsByTagNameNS($wsseNamespace, 'Username')->length == 0) {
throw new SoapFault("auth", 'Authentication error - Missing Username node');
}
if ($soapEnvelope->getElementsByTagNameNS($wsseNamespace, 'Password')->length == 0) {
throw new SoapFault("auth", 'Authentication error - Missing Password node');
}
// SOAPServer handle requests method
$server->handle();
这是一个污点,但它确实有效。