PHP SoapClient: Unknown required WSDL extension

生来就可爱ヽ(ⅴ<●) 提交于 2019-11-29 01:30:45

问题


I'm trying to implement a Web Service running on an SAP PI system. The WSDL I got looks like this:

<?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>

My PHP file looks like this (nothing more in it currently):

<?php 
$client = new SoapClient('test.wsdl');
?> 

When I'm running my script, I get the following error thrown:

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

I tried searching for the error on google and StackOverflow, and also checked the comments on php.net, but I can't seem to figure out what I'd have to change in order to get this Service running. I also tried to open the WSDL extension URL, it seems to exist.

Can someone throw me a bone here? I tried removing the extension URL, that results in the following error:

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

回答1:


The only solution I can think of at this point is to update your UsingPolicy tag:

Change the tag:

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

to this:

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



回答2:


This isn't really the correct answer in a SAP environment. In your URL for the WSDL, you'll see /ws_policy/ - change this to /standard/ and you'll be able to use the PHP SoapClient class to consume the web service without having to maintain a local modified copy of the WSDL. You can see the same on a SAP blog here (login probably required).




回答3:


For new versions the URL is not containing anymore the "ws_policy" instead there is a 0 (standard)or 1 (policy)

Example:

....wsdl/flv_10002A111AD1/bndg_url/.... (ws_policy)

....wsdl/flv_10002A101AD1/bndg_url/.... (standard)

Credits to Rafa Martinez




回答4:


Seems to be a bug in PHP SOAPServer, or a missing extension compatibility, and it hasn't been solved yet, at least in PHP 5.6.31.

The only solution I could find was to set required UsingPolicy to false, as suggested in the accepted response:

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

But clients could access the SOAP service without authentication, which is a serious security issue. So, I tried to manually check that the security data is sent by the client.

$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();

It's a dirt trick, but it works.



来源:https://stackoverflow.com/questions/16805488/php-soapclient-unknown-required-wsdl-extension

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!