Consuming Webservice SOAP with PHP - Header problem

Asked

Viewed 1,067 times

0

I am trying to consume a SOAP webservice using PHP but the access returns me message stating that the user validation was not done correctly. The XML I need to send is the following:

    <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:aut="http://servicos.saude.gov.br/wsdl/cmd/mensageria/v1r0/autenticacaocmd" xmlns:con="http://servicos.saude.gov.br/cmd/v1/contatoassistencialservice">
<soap:Header  xmlns:soap="http://www.w3.org/2003/05/soap-envelope"  xmlns:aut="http://servicos.saude.gov.br/wsdl/cmd/mensageria/v1r0/autenticacaocmd">
<wsse:Security  soap:mustUnderstand="true" 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 wsu:Id="UsernameToken-91A6C9ADF539A7475514438193926252">
            <wsse:Username>XXXXXXXXXXX</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">XXXXXXXXXXXXXX</wsse:Password>
         </wsse:UsernameToken>
</wsse:Security>
<aut:AutenticacaoCMD>
<aut:cpf>XXXXXXXXX</aut:cpf>
<aut:senha>XXXXXXXX</aut:senha>
</aut:AutenticacaoCMD>
</soap:Header>
   <soap:Body>
      <con:RequestCancelarContatoAssistencial>
         <con:codigoContatoAssistencial>XXXXXXXXXXXX</con:codigoContatoAssistencial>
      </con:RequestCancelarContatoAssistencial>
   </soap:Body>
</soap:Envelope>

If I take this XML and test using Soapui the service is consumed correctly, but direct in PHP gives error.

The last attempt was to send the integer XML as parameter:

$soapServer = 'https://servicoshm.saude.gov.br/cmd/ContatoAssistencialService/v1r0?wsdl';

$ns = 'http://servicos.saude.gov.br/wsdl/cmd/mensageria/v1r0/autenticacaocmd';

$arrContextOptions=array("ssl"=>array( "verify_peer"=>false, "verify_peer_name"=>false,'crypto_method' => STREAM_CRYPTO_METHOD_TLS_CLIENT));

$options = array(
    'soap_version'=>SOAP_1_2,
    'exceptions'=>true,
    'trace'=>1,
    'cache_wsdl'=>WSDL_CACHE_NONE,
    'stream_context' => stream_context_create($arrContextOptions)
);

$function   = 'cancelarContatoAssistencial';

try {

    $soapClient = new SoapClient($soapServer,$options);

    $xml = '
    <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:aut="http://servicos.saude.gov.br/wsdl/cmd/mensageria/v1r0/autenticacaocmd" xmlns:con="http://servicos.saude.gov.br/cmd/v1/contatoassistencialservice">
    <soap:Header  xmlns:soap="http://www.w3.org/2003/05/soap-envelope"  xmlns:aut="http://servicos.saude.gov.br/wsdl/cmd/mensageria/v1r0/autenticacaocmd">
    <wsse:Security  soap:mustUnderstand="true" 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 wsu:Id="UsernameToken-91A6C9ADF539A7475514438193926252">
                <wsse:Username>XXXXXXXX</wsse:Username>
                <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">XXXXXXXXXX</wsse:Password>
             </wsse:UsernameToken>
    </wsse:Security>
    <aut:AutenticacaoCMD>
    <aut:cpf>XXXXXXXXXX</aut:cpf>
    <aut:senha>XXXXXXXXX</aut:senha>
    </aut:AutenticacaoCMD>
    </soap:Header>
       <soap:Body>
          <con:RequestCancelarContatoAssistencial>
             <con:codigoContatoAssistencial>XXXXXXXXXX</con:codigoContatoAssistencial>
          </con:RequestCancelarContatoAssistencial>
       </soap:Body>
    </soap:Envelope>
    ';

    $retorno = $soapClient->cancelarContatoAssistencial(new SoapVar($xml, XSD_ANYXML));

} catch ( SoapFault $fault ) {

    echo '<pre>' ;
    print_r($soapClient->__getLastRequest());
    print_r($fault);
    echo '</pre>' ;
}

I also tried using the setSoapHeaders function to mount the header:

$soapServer = 'https://servicoshm.saude.gov.br/cmd/ContatoAssistencialService/v1r0?wsdl';

$ns = 'http://servicos.saude.gov.br/wsdl/cmd/mensageria/v1r0/autenticacaocmd';

$arrContextOptions=array("ssl"=>array( "verify_peer"=>false, "verify_peer_name"=>false,'crypto_method' => STREAM_CRYPTO_METHOD_TLS_CLIENT));

$options = array(
    'soap_version'=>SOAP_1_2,
    'exceptions'=>true,
    'trace'=>1,
    'cache_wsdl'=>WSDL_CACHE_NONE,
    'stream_context' => stream_context_create($arrContextOptions)
);

$location =  array('location' => 'https://servicoshm.saude.gov.br/cmd/ContatoAssistencialService/v1r0' );

$function   = 'cancelarContatoAssistencial';

$arguments['RequestCancelarContatoAssistencial'] = array(  'codigoContatoAssistencial'   => 'XXXXXXXXXXXXXXXXXXXXX' );

try {

    $soapClient = new SoapClient($soapServer,$options);

    $security = '
    <wsse:Security  soap:mustUnderstand="true" 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 wsu:Id="UsernameToken-91A6C9ADF539A7475514438193926252">
                <wsse:Username>XXXXXXXXX</wsse:Username>
                <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">XXXXXXXXXXX</wsse:Password>
             </wsse:UsernameToken>
    </wsse:Security>
    ';

    $auth = '
        <aut:AutenticacaoCMD>
        <aut:cpf>XXXXXXXX</aut:cpf>
        <aut:senha>XXXXXXXXXX</aut:senha>
        </aut:AutenticacaoCMD>
    ';

     $header = array();
     $header[] = new SoapHeader($ns, 'Security', new SoapVar($security, XSD_ANYXML), true);
     $header[] = new SoapHeader($ns, 'AutenticacaoCMD', new SoapVar($auth, XSD_ANYXML), false);

     $soapClient->__setSoapHeaders($header);

    $retorno = $soapClient->__soapCall($function, $arguments, $location);

} catch ( SoapFault $fault ) {

    echo '<pre>' ;
    print_r($soapClient->__getLastRequest());
    print_r($fault);
    echo '</pre>' ;
}

Following the guidelines of POST I consumed the service using the suggested code (using the real data) and the same returned me validation error. When debugging XML I realized that the tag Usernametoken was missing.

I used the code below and the service was successfully consumed. Thank you very much for your help.

$soapServer = 'https://servicoshm.saude.gov.br/cmd/ContatoAssistencialService/v1r0?wsdl';

$arrContextOptions = array("ssl" => array("verify_peer" => false , "verify_peer_name" => false , 'crypto_method' => STREAM_CRYPTO_METHOD_TLS_CLIENT));

$options = array(
    'soap_version'=>SOAP_1_2,
    'exceptions'=>true,
    'trace'=>1,
    'cache_wsdl' => WSDL_CACHE_NONE,
    'stream_context' => stream_context_create($arrContextOptions)
);

try {

    $securityNS = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';

    $auth = new stdClass();
    $auth->Username = new SoapVar('XXXXXXXX', XSD_STRING, null, null, 'Username', $securityNS);
    $auth->Password = new SoapVar('XXXXXXXX', XSD_STRING, null, null, 'Password', $securityNS);

    $token = new stdClass();
    $token->UsernameToken = new SoapVar($auth, SOAP_ENC_OBJECT, null, null, 'UsernameToken', $securityNS);

    $security = new SoapVar($token, SOAP_ENC_OBJECT, null, null, 'Security', $securityNS);

    $headers[] = new SoapHeader($securityNS , 'Security' , $security , true);

    $soapClient = new SoapClient($soapServer , $options);

    $ns = 'http://servicos.saude.gov.br/wsdl/cmd/mensageria/v1r0/autenticacaocmd';

    $auth = new stdClass();
    $auth->cpf = new SoapVar('XXXXXXXX', XSD_STRING, null, null, 'cpf', $ns);
    $auth->senha = new SoapVar('XXXXXXXX', XSD_STRING, null, null, 'senha', $ns);
    $autenticacaoCMD = new SoapVar($auth, SOAP_ENC_OBJECT, null, null, 'AutenticacaoCMD', $ns);

    $headers[] = new SoapHeader($ns , 'AutenticacaoCMD' , $autenticacaoCMD , false);

    $soapClient->__setSoapHeaders($headers);

    $arguments = new stdClass();
    $arguments->codigoContatoAssistencial = 'XXXXXXXXXXXXXXXXXXXX';

    $retorno = $soapClient->cancelarContatoAssistencial($arguments);

} catch ( SoapFault $fault ) {

    echo '<pre>' ;
    var_dump($fault);
    echo '</pre>' ;
}
  • Post the shapes you have tried to consume so far.

  • @Gabrielheming follows reply below

  • 1

    Do not create answers to insert new information, always edit the question. The first question you should understand is that Soapclient abstracts almost all of the work (not all of it) of manipulating XML, so you don’t send XML to consume WS. The only point that should be treated differently are the headers. Once I have time, or another user, can write a response.

1 answer

0


Assessing what is described via WSDL and interpreted via Soapui, the code below meets the need:

<?php

$soapServer = 'https://servicoshm.saude.gov.br/cmd/ContatoAssistencialService/v1r0?wsdl';

$arrContextOptions = array("ssl" => array("verify_peer" => false , "verify_peer_name" => false , 'crypto_method' => STREAM_CRYPTO_METHOD_TLS_CLIENT));

$options = array(
    'soap_version'=>SOAP_1_2,
    'exceptions'=>true,
    'trace'=>1,
    'cache_wsdl' => WSDL_CACHE_NONE,
    'stream_context' => stream_context_create($arrContextOptions)
);

try {
    $soapClient = new SoapClient($soapServer , $options);   

    $ns = 'http://servicos.saude.gov.br/wsdl/cmd/mensageria/v1r0/autenticacaocmd';

    $auth = new stdClass();
    $auth->cpf = new SoapVar('111.111.111-11', XSD_STRING, null, null, 'cpf', $ns);
    $auth->senha = new SoapVar('pass', XSD_STRING, null, null, 'senha', $ns);
    $autenticacaoCMD = new SoapVar($auth, SOAP_ENC_OBJECT, null, null, 'AutenticacaoCMD', $ns);

    $header = new SoapHeader($ns , 'AutenticacaoCMD' , $autenticacaoCMD , false);

    $soapClient->__setSoapHeaders($header);     

    $arguments = new stdClass();
    $arguments->codigoContatoAssistencial = 'código';

    $retorno = $soapClient->cancelarContatoAssistencial($arguments);

} catch ( SoapFault $fault ) {

    echo '<pre>' ;
    var_dump($fault);
    echo '</pre>' ;
}

The XML generated for WS consumption is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://servicos.saude.gov.br/cmd/v1/contatoassistencialservice" xmlns:ns2="http://servicos.saude.gov.br/wsdl/cmd/mensageria/v1r0/autenticacaocmd">
    <SOAP-ENV:Header>
        <ns2:AutenticacaoCMD>
            <ns2:cpf>111.111.111-11</ns2:cpf>
            <ns2:senha>pass</ns2:senha>
        </ns2:AutenticacaoCMD>
    </SOAP-ENV:Header>

    <SOAP-ENV:Body>
        <ns1:RequestCancelarContatoAssistencial>
            <ns1:codigoContatoAssistencial>código</ns1:codigoContatoAssistencial>
        </ns1:RequestCancelarContatoAssistencial>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

If you really need to add the tag Security, just turn the variable $header in an array (will now be called $headers) and add as many headers as needed to add a new header:

<?php

$soapServer = 'https://servicoshm.saude.gov.br/cmd/ContatoAssistencialService/v1r0?wsdl';

$arrContextOptions = array("ssl" => array("verify_peer" => false , "verify_peer_name" => false , 'crypto_method' => STREAM_CRYPTO_METHOD_TLS_CLIENT));

$options = array(
    'soap_version'=>SOAP_1_2,
    'exceptions'=>true,
    'trace'=>1,
    'cache_wsdl' => WSDL_CACHE_NONE,
    'stream_context' => stream_context_create($arrContextOptions)
);

try {

    $securityNS = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';

    $auth = new stdClass();
    $auth->Username = new SoapVar('user', XSD_STRING, null, null, 'Username', $securityNS);
    $auth->Password = new SoapVar('pass', XSD_STRING, null, null, 'Password', $securityNS);
    $usernameToken = new SoapVar($auth, SOAP_ENC_OBJECT, null, null, 'UsernameToken', $securityNS);
    $security = new SoapVar($usernameToken, SOAP_ENC_OBJECT, null, null, 'Security', $securityNS);

    $headers[] = new SoapHeader($securityNS , 'Security' , $security , true);

    $soapClient = new SoapClient($soapServer , $options);   

    $ns = 'http://servicos.saude.gov.br/wsdl/cmd/mensageria/v1r0/autenticacaocmd';

    $auth = new stdClass();
    $auth->cpf = new SoapVar('111.111.111-11', XSD_STRING, null, null, 'cpf', $ns);
    $auth->senha = new SoapVar('pass', XSD_STRING, null, null, 'senha', $ns);
    $autenticacaoCMD = new SoapVar($auth, SOAP_ENC_OBJECT, null, null, 'AutenticacaoCMD', $ns);

    $headers[] = new SoapHeader($ns , 'AutenticacaoCMD' , $autenticacaoCMD , false);

    $soapClient->__setSoapHeaders($headers);    


    $arguments = new stdClass();
    $arguments->codigoContatoAssistencial = 'código';

    $retorno = $soapClient->cancelarContatoAssistencial($arguments);

} catch ( SoapFault $fault ) {

    echo '<pre>' ;
    var_dump($fault);
    echo '</pre>' ;
}

The XML generated for WS consumption is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://servicos.saude.gov.br/cmd/v1/contatoassistencialservice" xmlns:ns2='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' xmlns:ns3="http://servicos.saude.gov.br/wsdl/cmd/mensageria/v1r0/autenticacaocmd">
    <SOAP-ENV:Header>
        <ns2:Security SOAP-ENV:mustUnderstand="1">
            <ns2:Username>user</ns2:Username>
            <ns2:Password>pass</ns2:Password>
        </ns2:Security>

        <ns3:AutenticacaoCMD>            
            <ns3:cpf>111.111.111-11</ns3:cpf>
            <ns3:senha>pass</ns3:senha>
        </ns3:AutenticacaoCMD>
    </SOAP-ENV:Header>

    <SOAP-ENV:Body>
        <ns1:RequestCancelarContatoAssistencial>
            <ns1:codigoContatoAssistencial>código</ns1:codigoContatoAssistencial>
        </ns1:RequestCancelarContatoAssistencial>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
  • I tried the 2 informed codes and both return the error "Forced Circuit Exception" by PHP. Copying these 2 generated XML and executing them directly in Soapui returns the same error: "Forced Circuit Exception"

  • This error also occurs with your XML, which I assume is the fact that you do not have correct data for authentication. Or, the service is out.

  • Use the codeContactAssistencial: 00000000-0000-4000-8000-000000000026. The rest of the data can send any string. In the example XML it returns the correct error (authentication failure). In the XML generated by PHP it returns "Forced Circuit Exception"

  • @Brunoaugusto fixed, the problem was the version of WSDL

  • I ran your code again, keeps returning error. What was the fix you did? It was only the 'soap_version'=>SOAP_1_2 ?

  • The first example was working. The second had a namespace problem, it was duplicated. I tested the two codes and they are functional

  • I tested your code and realized that the validation error occurred because the Usernametoken tag was missing. I corrected the code to include this TAG and the service was successfully consumed. I edited the POST so that the code can help those who are also having this kind of problem. Thank you so much for the help!

  • @Brunoaugusto I posted two codes, one with the tag and the other without. In my environment, it was not necessary to use the tag. If solved, mark as correct and +1 if possible

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.