Consume Webservice SOAP with PHP - Problem with header

0

I am trying to consume a SOAP webservice using PHP however access returns me message stating that user validation was not done correctly. The XML that 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 get this XML and test using SoapUI the service is consumed correctly, however direct in PHP it gives error.

The last attempt was to send the entire XML as a 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 tried to use 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 POST guidelines I consumed the service using the suggested code (using the actual data) and it returned the validation error. When I debugged the XML, I realized I was missing the UsernameToken tag.

I used the code below and the service was successfully consumed. Many thanks for the 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>' ;
}
    
asked by anonymous 07.11.2018 / 19:40

1 answer

0

Evaluating what is described via WSDL and interpreted via SoapUI, the code below fulfills 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 Security tag, just change the $header variable into an array (now it will be called $headers ) and add as many headers as necessary 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>
    
08.11.2018 / 13:56