13

我正在尝试实现在 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=&amp;senderService=BS_ORS&amp;receiverParty=&amp;receiverService=&amp;interface=request_SO&amp;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=&amp;senderService=BS_ORS&amp;receiverParty=&amp;receiverService=&amp;interface=request_SO&amp;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');
?>

当我运行我的脚本时,我收到以下错误:

致命错误:未捕获的 SoapFault 异常:[WSDL] SOAP-ERROR: Parsing WSDL: Unknown required WSDL extension 'http://schemas.xmlsoap.org/ws/2004/09/policy' in /srv/www/htdocs/wsdl。 php:2 堆栈跟踪:#0 /srv/www/htdocs/wsdl.php(2): SoapClient->SoapClient('test.wsdl') #1 {main} 抛出 /srv/www/htdocs/wsdl.php在第 2 行

我尝试在 Google 和 Stack Overflow 上搜索错误,还检查了 php.net 上的评论,但我似乎无法弄清楚我必须更改什么才能运行此服务。我也尝试打开 WSDL 扩展 URL,它似乎存在。

有人可以在这里扔我一根骨头吗?我尝试删除扩展 URL,导致以下错误:

致命错误:未捕获的 SoapFault 异常:[WSDL] SOAP-ERROR: Parsing WSDL: Unexpected WSDL element in /srv/www/htdocs/wsdl.php:2 堆栈跟踪:#0 /srv/www/htdocs/wsdl.php(2 ): SoapClient->SoapClient('test.wsdl') #1 {main} 在第 2 行的 /srv/www/htdocs/wsdl.php 中抛出

4

4 回答 4

23

此时我能想到的唯一解决方案是更新您的 UsingPolicy 标签:

更改标签:

<wsp:UsingPolicy wsdl:required="true"/> 

对此:

<wsp:UsingPolicy wsdl:required="false"/>
于 2013-05-29T04:50:37.077 回答
16

在 SAP 环境中,这并不是真正的正确答案。在 WSDL 的 URL 中,您将看到/ws_policy/- 将其更改为/standard/,您将能够使用 PHP SoapClient 类来使用 Web 服务,而无需维护 WSDL 的本地修改副本。您可以在此处的 SAP 博客上看到相同的内容(可能需要登录)。

于 2014-02-07T10:08:06.837 回答
11

对于新版本,URL 不再包含“ws_policy”,而是有 0(标准)或 1(策略)

例子:

....wsdl/flv_10002A1 1 1AD1/bndg_url/....(ws_policy)

....wsdl/flv_10002A1 0 1AD1/bndg_url/....(标准)

归功于拉法·马丁内斯

于 2016-08-12T02:30:26.587 回答
0

似乎是 PHP SOAPServer 中的一个错误,或者缺少扩展兼容性,并且尚未解决,至少在 PHP 5.6.31 中。

我能找到的唯一解决方案是设置 required UsingPolicyto 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();

这是一个肮脏的把戏,但它有效。

于 2017-11-10T11:52:59.793 回答