PHP SoapClient: Unknown required WSDL extension
j'essaie d'implémenter un service Web fonctionnant sur un système SAP PI. Le WSDL j'ai obtenu ressemble à ceci:
<?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>
Mon fichier PHP ressemble à ceci (rien de plus en ce moment):
<?php
$client = new SoapClient('test.wsdl');
?>
Quand j'exécute mon script, j'obtiens l'erreur suivante jeté:
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
j'ai essayé de chercher l'erreur sur google et StackOverflow, et vérifier les commentaires sur php.net mais je n'arrive pas à comprendre ce que je dois modifier pour obtenir ce Service exécuter. J'ai aussi essayé d'ouvrir L'URL de l'extension WSDL, elle semble exister.
quelqu'un Peut-il me jeter un os ici? J'ai essayé de supprimer L'URL de l'extension, qui entraîne l'erreur suivante:
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
4 réponses
la seule solution à laquelle je peux penser à ce stade est de mettre à jour votre étiquette UsingPolicy:
Modifier la balise:
<wsp:UsingPolicy wsdl:required="true"/>
à:
<wsp:UsingPolicy wsdl:required="false"/>
ce n'est pas vraiment la bonne réponse dans un environnement SAP. Dans votre URL pour la WSDL, vous verrez /ws_policy/
- modifier ce /standard/
et vous pourrez utiliser la classe PHP SoapClient pour consommer le service web sans avoir à maintenir une copie modifiée locale de la WSDL. Vous pouvez voir la même chose sur un blog SAP ici (connexion probablement requise).
pour les nouvelles versions L'URL ne contient plus le "ws_policy"" a la place, il y a un 0 (standard)ou un 1 (policy)
Exemple:
....wsdl/flv_10002A111AD1/bndg_url/.... (ws_policy)
....wsdl/flv_10002A1 01AD1/bndg_url/.... (standard)
Crédits Rafa Martinez
semble être un bug dans PHP SOAPServer, ou une compatibilité d'extension manquante, et il n'a pas encore été résolu, au moins en PHP 5.6.31.
La seule solution que j'ai pu trouver était de mettre obligatoire UsingPolicy
false
, tel que suggéré dans la réponse acceptée:
<wsp:UsingPolicy wsdl:required="false" />
mais les clients pouvaient accéder au service SOAP sans authentification, ce qui pose un sérieux problème de sécurité. Donc, j'ai essayé de vérifier manuellement que les données de sécurité sont envoyées par le 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();
c'est un tour de passe-passe, mais ça marche.