Question

j'essaie d'appeler un partenaire WS en utilisant usernameToken.J'utilise pour ça ws02 wsf_2.0.0 sous php5.2.x et ça déchire.Nous souhaitons maintenant migrer vers une solution différente basée sur php5.3, heureusement, ws02 fournit une balise 2.1.0 compatible avec php5.3.Je prends le temps de lire les nouveautés et la documentation de cette nouvelle version et notamment concernant le usernameToken.J'ai compris que cette version utilise la signature concernant le usernameToken via un certificat et une clé privée.Je suppose que c'est dû à la politique AsymetricTransportBinding.Dans mon cas, je ne voulais rien signer via un certificat ou autre.J'ai lu aussi que ws02 fournit une sorte de solution de secours dans un fichier XML séparé pour éviter toute signature.

Après avoir lu de nombreux messages et forums, j'ai besoin de l'aide de la communauté car je suis totalement bloqué.

Voici le code utilisé pour demander le WS en php5.3 - wsf 2.1.0 (en utilisant HTTP)

$policy   = new \WSPolicy( $policy ); ( $policy is the one from the call_back folder with a file_get_contents() )

$security = new \WSSecurityToken( array(
  'user'                    => 'my_username',
  'password'                => 'my_password',
  'passwordType'            => 'Digest',
  'ttl'                     => '300'
));

$this->oSoapClient = new \WSClient( array(
  wsdl:          http://www.xxx.xx/comparatorservices/CalculationService?WSDL
  to:            http://www.xxx.xx/comparatorservices/CalculationService
  useWSA:        true
  useSOAP:       1.1,
  policy:        $policy,
  securityToken: $security
));

$proxy = $this->oSoapClient->getProxy();
$response = $proxy->wykonajKalkulacje( $MySuperRequestObject );

A cette étape :

  1. J'ai activé les traces de débogage (log niveau 4)
  2. Je confirme que mon "to" utilise http selon la définition wsdl

    wsdl: port name = "CalculServiceHttpport" binding = "tns: CalculServiceHttpBinding" wsdlsoap: adresse location = "http: //www.xxxx.xx/comparatorServices/calculService" / wsdl: port: port

Maintenant, à partir des journaux de débogage, j'obtiens ceci :

[Wed Jul 25 05:22:53 2012] [error] rampart_in_handler.c(91) [rampart]SOAP header cannot be found.
[Wed Jul 25 05:22:53 2012] [error] phase.c(224) Handler RampartInHandler invoke failed within phase Security
[Wed Jul 25 05:22:53 2012] [error] engine.c(657) Invoking phase Security failed
[Wed Jul 25 05:22:53 2012] [error] engine.c(262) Invoking operation specific phases failed for operation __OPERATION_OUT_IN__
[Wed Jul 25 05:22:53 2012] [error] /home/agruet/08_KRK_sources/wso2-wsf-php-src-2.1.0/src/wsf_wsdl.c(1226)      [wsf_wsdl] Response envelope not found

Ma première idée a donc été de renifler le trafic et surtout l'en-tête SOAP entre le travail ( wsf_2.0.0 / php5.2.x ) et le cassé ( wsf_2.1.0 / php5.3 )

Voici le 2.0.0 (fonctionnant)

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Header>
    <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">

        <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <wsse:Username>my_username</wsse:Username>

            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">
              hashed(my_password)
            </wsse:Password>

            <wsse:Nonce>hashed</wsse:Nonce>
            <wsu:Created>2012-07-26T20:40:26.991Z</wsu:Created>

        </wsse:UsernameToken>
    </wsse:Security>
</soapenv:Header>

Et le 2.1.0 (ne fonctionne pas/cassé)

         <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
       <soapenv:Header>
         <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">

        <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">

            <wsse:Username>my_username</wsse:Username>
            <wsse:Password
                Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">hashed(my_password)</wsse:Password>
            <wsse:Nonce>hashed</wsse:Nonce>
            <wsu:Created>2012-07-25T00:44:56.758Z</wsu:Created>
        </wsse:UsernameToken>
    </wsse:Security>
</soapenv:Header>

Comme vous pouvez le voir, la seule différence vient de l'espace de noms wsse:Security.( xmlns manquant:soapenv="http://schemas.xmlsoap.org/soap/envelope/ )

Et c'est tout ...

L'inspection du rempart_in_handler.c à la ligne 91 selon le journal de débogage dit :

soap_header = axiom_soap_envelope_get_header(soap_envelope, env);
    if(!soap_header)
    {
        /*No SOAP header, so no point of proceeding. FAIL*/
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]SOAP header cannot be found.");
        return AXIS2_FAILURE;
    }

C'est à dire ouais....le soap_header est faux..mais pourquoi?Y a-t-il un gars intelligent pour expliquer ce qui ne va pas ?

note 1 :J'ai inspecté la politique envoyée au partenaire WS depuis le serveur de travail (2.0.0), il semble qu'un AsymetricBinding soit utilisé...ce qui est bizarre tant que dans la version 2.0.0 nous n'avons fourni aucun certificat ni clé.

note 2 :J'ai également essayé d'utiliser un jeton de nom d'utilisateur signé avec les paramètres de tableau WSPolicy Object classiques - j'ai créé un certificat x509 et une clé privée, puis j'ai utilisé les fonctions pour charger ces fichiers et j'ai utilisé les paramètres du tableau pour le charger dans le constructeur WSSecurity...mais je reçois la même erreur / Renifler est pénible car les données sont cryptées ou quelque chose comme ça (ce qui semble être normal de cette façon)

note 3 :Actuellement testé sur Ubuntu10.04-3LTS avec les packages php précompilés d'apt-get

AIDE SVP !

Était-ce utile?

La solution

J'ai finalement trouvé le problème et j'ai corrigé le rempart_in_handler.c:91

Le problème venait de la réponse et non de la demande...J'ai inspecté via un renifleur TCP et la réponse du partenaire WS a été faite sans aucun savon : en-tête.

Conforme ou non aux standards, avec la dernière version ( 2.0.0 ) cela fonctionnait.J'ai donc décidé de modifier un peu le code du fichier rempart_in_handler.c pour renvoyer un succès dans le cas où l'en-tête du savon est manquant...

A mon avis et PLZ corrigez moi si je me trompe :

Le test sur la réponse soapHeader a certainement été ajouté en raison du transport asymetricBinding et du nouveau cas de jeton de nom d'utilisateur signé.Cependant, si nous voulons utiliser usernametoken sans signer ( via le fichier Policy.xml de base ) ET la réponse est faite sans savon:Header ;alors le rempart retournera toujours un échec...

De plus, j'ai analysé le code php sous le dossier scripts/ concernant la façon dont wsf gère la réponse et j'ai vu sur ce fichier : wsf_wsdl.php sous la fonction wsf_process_response() :

if($response_header_string && !empty($response_header_string)) {
    $header_dom = new DomDocument();
    $header_dom->preserveWhiteSpace = FALSE;
    $header_dom->loadXML($response_header_string);
}

Cela signifie que du côté php, lorsque les données sont reçues, wsf/php suppose un cas sans aucun soapHeader...(il n'y a pas d'échec si le soapHeader est manquant) Super bizarre !?

Enfin, j'ai trouvé un bug bizarre sur les deux wsf_wsdl_serialization.php et wsf_wsdl_deserialization.php des dossiers.

Par exemple, si vous prévoyez d'envoyer et/ou de recevoir des paramètres/valeurs avec une chaîne comme celle-ci :

                            "110% Sigma of something" 

Il échouera et créera une erreur de segmentation pendant le processus de sérialisation/désérialisation !

Maintenant je me demande pourquoi ?Mais à première vue, c'est sûr, "110% Sig.." contient "% S" et c'est assez fermé de "%s"...

Je pense que ce bug est celui mentionné ici :

http://old.nabble.com/WSF-PHP-server-segfault-on-wsf_wsdl_serialization.php---td24329956.html

Si je change le S par D ou autre chose ça marche...

Quelle douleur...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top