2017-06-23 1 views
6

Je dois ajouter l'en-tête complexe suivant avec différents espaces de noms et types à mon en-tête SoapClient.En-têtes complexes pour PHP SoapClient

<soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"> 
    <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
     <wsse:UsernameToken> 
      <wsse:Username>****</wsse:Username> 
      <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">*****</wsse:Password> 
     </wsse:UsernameToken> 
    </wsse:Security> 
    <wsa:Action>/IntS5/S5WS</wsa:Action> 
</soapenv:Header> 

Comme proposé dans d'autres réponses que j'essayé l'approche suivante dans mon php project.Since je besoin WSA Aborder, je mis le WSA: Action avec en-tête de sécurité ensemble.

$header_part = '<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">' 
     . '<wsse:UsernameToken><wsse:Username>****</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">****</wsse:Password>' 
     . '</wsse:UsernameToken></wsse:Security><wsa:Action>/IntS5/S5WS</wsa:Action>'; 

    $soap_var_header = new SoapVar($header_part, XSD_ANYXML, null, null, null); 
    $soap_header = new SOAPHeader('http://www.w3.org/2005/08/addressing', 'wsa', $soap_var_header); 
    $client->__setSoapHeaders($soap_header); 

Quelque chose comme __soapCall me renvoie l'erreur suivante.

SoapFault exception: [Client] DTD n'est pas supporté par SOAP.Je ne suis pas sûr si c'est lié à l'en-tête ou aux paramètres du putCall. Quelqu'un peut-il m'aider?

EDIT: Le problème est probablement lié à l'espace de nom de HEADER/Envelope.

La requête envoyée au serveur ressemble à ceci. MISE À JOUR

<?xml version="1.0" encoding="UTF-8"?> 
        <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://ws.s5.mediasat.de/" xmlns:ns2="http://www.w3.org/2005/08/addressing"> 
         <env:Header> 
          <wsse:Security env:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
           <wsse:UsernameToken> 
            <wsse:Username>****</wsse:Username> 
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">*****</wsse:Password> 
           </wsse:UsernameToken> 
          </wsse:Security> 
          <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">/IntS5/S5WS</wsa:Action> 
         </env:Header> 
         <env:Body> 
          <ns1:putCall> 
           <transaction>createIncident</transaction> 
           <transactionSender>Request</transactionSender> 
           <caseDataModel> 
            <senderId>7</senderId> 
            <ticketTypeId>102</ticketTypeId> 
            <title>test</title> 
            <priorityId>101</priorityId> 
            <categoryId>128</categoryId> 
            <description>Description</description> 
            <ticketNumberSender>INCC00000743809</ticketNumberSender> 
            <createTypeId>701</createTypeId> 
            <serviceId>B001APP05K</serviceId> 
            <categoryId>128</categoryId> 
            <serviceRecipientId>77888</serviceRecipientId> 
            <serviceLocationSAPCode>V135</serviceLocationSAPCode> 
           </caseDataModel> 
          </ns1:putCall> 
         </env:Body> 
        </env:Envelope> 

La demande qui fonctionne sur l'interface utilisateur SOAP

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.s5.mediasat.de/"> 
    <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"> 
     <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
      <wsse:UsernameToken> 
       <wsse:Username>***</wsse:Username> 
       <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">***</wsse:Password> 
      </wsse:UsernameToken> 
     </wsse:Security> 
     <wsa:Action>/IntS5/S5WS</wsa:Action> 
    </soapenv:Header> 
    <soapenv:Body> 
     <ws:putCall> 
      <transaction>createIncident</transaction> 
      <transactionSender>Request</transactionSender> 
      <caseDataModel> 
       <senderId>7</senderId> 
       <ticketTypeId>102</ticketTypeId> 
       <title>test</title> 
       <priorityId>101</priorityId> 
       <categoryId>128</categoryId> 
       <description>Description</description> 
       <ticketNumberSender>INCC00000743809</ticketNumberSender> 
       <createTypeId>701</createTypeId> 
       <serviceId>B001APP05K</serviceId> 
       <categoryId>128</categoryId> 
       <serviceRecipientId>77888</serviceRecipientId> 
       <serviceLocationSAPCode>V135</serviceLocationSAPCode> 
      </caseDataModel> 
     </ws:putCall> 
    </soapenv:Body> 
</soapenv:Envelope> 

Y at-il de toute façon à définir/remplacer l'espace de noms pour l'en-tête?

+0

Y0ou devrait être en mesure d'identifier l'erreur en traçant/de dumping. – mikep

+0

$ client = nouveau \ SoapClient (dirname (__ FILE__).DIRECTORY_SEPARATOR. $ url, array ('exceptions' => true, 'trace' => true)); Le suivi est déjà activé. –

+0

@mikep il complais que la réponse retournée ne soit pas une page XML valide is.J'ai essayé la requête générée dans soap. J'obtiens une exception java liée à l'élément racine. –

Répondre

2

Vous devez générer l'en-tête de façon procédurale au lieu d'utiliser la chaîne.

Exemple:

<?php 

$client = new SoapClient(null, array(
    'location' => "http://localhost/soap/", 
    'uri' => "http://ws.s5.mediasat.de/", 
    'soap_version' => SOAP_1_2 
)); 

$username = '***'; 
$password = '***'; 
$sec_namespace = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'; 
$wsa_namespace = 'http://www.w3.org/2005/08/addressing'; 

// prepare security token 
$node1 = new \SoapVar($username, XSD_STRING, null, null, 'Username', $sec_namespace); 

$xml = new XMLWriter(); // this is a little hacky, but no other way to set the type as far as I know 
$xml->openMemory(); 
$xml->startElementNS('wsse', 'Password',$sec_namespace); 
$xml->writeAttribute('Type', 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText'); 
$xml->Text($password); 
$xml->endElement(); 
$node2 = new \SoapVar($xml->outputMemory(), XSD_ANYXML); 

$token = new \SoapVar(array($node1, $node2), SOAP_ENC_OBJECT, null, null, 'UsernameToken', $sec_namespace); 
$security = new \SoapVar(array($token), SOAP_ENC_OBJECT, null, null, 'Security', $sec_namespace); 
$soap_header_sec = new \SOAPHeader($sec_namespace, 'Security', $security, true); 

// prepare action token 
$action = new \SoapVar('/IntS5/S5WS', XSD_STRING, null, null, 'Action', $wsa_namespace); 
$soap_header_action = new \SOAPHeader($wsa_namespace, 'Action', $action, false); 

// set prepared headers 
$client->__setSoapHeaders(
    [$soap_header_sec,$soap_header_action] 
); 

$client->putCall(); 

Cela produira l'enveloppe valable avec tous les espaces de noms définis:

<?xml version="1.0" encoding="utf-8"?> 
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://ws.s5.mediasat.de/" xmlns:ns2="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:ns3="http://www.w3.org/2005/08/addressing" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:enc="http://www.w3.org/2003/05/soap-encoding"> 
    <env:Header> 
    <ns2:Security env:mustUnderstand="true"> 
     <ns2:UsernameToken> 
     <ns2:Username>***</ns2:Username> 
     <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">***</wsse:Password> 
     </ns2:UsernameToken> 
    </ns2:Security> 
    <ns3:Action>/IntS5/S5WS</ns3:Action> 
    </env:Header> 
    <env:Body> 
    <ns1:putCall env:encodingStyle="http://www.w3.org/2003/05/soap-encoding" /> 
    </env:Body> 
</env:Envelope> 
+0

BTW il devrait être $ xml-> startElementNS ('ns2', 'Mot de passe', $ sec_namespace); –

+0

le problème est xmlns: env = "http://www.w3.org/2003/05/soap-envelope" si je pouvais le changer en "http://schemas.xmlsoap.org/soap/envelope/" le nouvelle demande générée works.is-ce possible? –

+0

@IlkerBaltaci pense que c'est SOAP 1.1, il suffit de changer dans '' soap_version '=> SOAP_1_2' en SOAP_1_1 – luki

0
  1. L'espace de nom "http://www.w3.org/2005/08/addressing" n'est pas lié au préfixe "wsa".

  2. Le "mustUnderstand" attribut doit utiliser le préfixe "env" et non "soapenv".

Vous pouvez déclarer l'espace de noms manquant localement. Il vous suffit de vous fixer header_part pour ressembler à ceci:

header_part = '<wsse:Security env:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">' 
    . '<wsse:UsernameToken><wsse:Username>****</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">****</wsse:Password>' 
    . '</wsse:UsernameToken></wsse:Security><wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">/IntS5/S5WS</wsa:Action>'; 

Note: Peut-être qu'il est évident, mais il est un peu dangereux de supposer que le préfixe pour le « http://www.w3.org/2003/05/soap-envelope » sera toujours « env ». Le cadre peut changer cela à tout moment. Si vous voulez être sur le côté vraiment sûr vous pouvez préférer lier l'espace de noms localement à un nouveau préfixe:

<wsse:Security soapenv:mustUnderstand="1" xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" ... 

Mais ayant un espace de noms lié à deux préfixes différents va rendre les choses encore plus difficiles à lire et à comprendre donc je dirait que c'est une question de goût.

+0

La question est de savoir comment ajouter xmlns: wsa = "http://www.w3.org/2005/08/addressing" à l'en-tête dans soapclient –

+0

j'ai changé le En-tête comme vous avez proposé mais le serveur m'envoie "ressemble à ce que nous n'avons pas de document XML" .I a copié tout le corps de la requête et collé à l'interface SOAP. Il me renvoie "L'application de la stratégie n'a pas réussi à authentifier la requête." puisque l'en-tête de sécurité n'est pas reconnu. –

+0

Pouvez-vous publier la demande complète qui est générée. – fhossfel