Skip to content

Instantly share code, notes, and snippets.

@gknapp
Last active March 12, 2022 19:17
Show Gist options
  • Save gknapp/bb4e4f009fc870db39c1 to your computer and use it in GitHub Desktop.
Save gknapp/bb4e4f009fc870db39c1 to your computer and use it in GitHub Desktop.
Add WSSE support to PHP's soapclient
<?php
class WsseHeader
{
const NS_WSSE = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd';
const NS_WSSEPSWD = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText';
public function build($username, $password)
{
$header = sprintf(
'<wsse:Security xmlns:wsse="%s" SOAP-ENV:mustUnderstand="1">' .
'<wsse:UsernameToken>' .
'<wsse:Username>%s</wsse:Username>' .
'<wsse:Password Type="%s">%s</wsse:Password>' .
'</wsse:UsernameToken>' .
'</wsse:Security>',
self::NS_WSSE, $username, self::NS_WSSEPSWD, $password
);
return new SoapHeader(self::NS_WSSE, 'wsse', new SoapVar($header, XSD_ANYXML));
}
}
class WsseClient extends SoapClient
{
public function setCredentials($username, $password)
{
$wsseHeader = new WsseHeader;
$header = $wsseHeader->build($username, $password);
$this->__setSoapHeaders(null);
$this->__setSoapHeaders($header);
}
}
// Construct as you would the built-in SoapClient, call setCredentials() when known
// http://www.php.net/manual/en/soapclient.soapclient.php
$soap = new WsseClient($wsdl, $options);
// ... once credentials are known
$soap->setCredentials($user, $pswd);
@lucasjsandrade
Copy link

Hi, I'm trying to connect a web service to days using your class, but I have a seemingly simple but very intriguing error, i am passing more than one address in the nameSpace,but when I make a soapcall, it concatenates a quotation mark that I am not able to change it.
I'M defines the const like this: const NS2_WSSE = 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" 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'
you can please help me?
your contriubuition can save me.

@gknapp
Copy link
Author

gknapp commented Jun 2, 2020

See example #2 in the PHP docs, $headers can be an array if you want to specify multiple.

This code is 6 years old now.

@lucasjsandrade
Copy link

Thanks, I'll test later, I solved the problem in another way, I used DomDocumente to create the XML and send a requirement with Curl, it took me several days to authenticate the old web service.

@deynerreinoso
Copy link

Hello, lucasjsandrade I have the same problem, can you paste some code to try if it works in my project?

@lucasjsandrade
Copy link

Hi deynerreinoso, i tried to implement this class but not success, I needed to find another solution,
I created the entire xml structure manually, whith DOMDocument and I called a soap request with Curl,

`
public function FunResolverObjeto($VObjectType,$VPropertyString,$servico){

    try {
            
            // * INSTANCIA UM NOVO OBJETO DOM XML
            $dom = new DOMDocument('1.0', 'utf-8');
            $dom->preserveWhiteSpace = false;
            $dom->formatOutput = true;
            // * SET TIMESTEMP TO HEADER
            setlocale(LC_TIME, 'pt_BR', 'pt_BR.utf-8', 'pt_BR.utf-8', 'portuguese');
            date_default_timezone_set('America/Sao_Paulo');
            $tm_created = gmdate('Y-m-d\TH:i:s\Z');
            $tm_expires = gmdate('Y-m-d\TH:i:s\Z', gmdate('U') + 86400);
    
            /*  createElement('TAG NAME') CREATE  TAGS  WITHOUT VALUES 
            *  createElement('TAG NAME', $VALOR) CREATE  TAGS WHITH VALUE
            *  TAGS DO HEADER                     
            */
    
            $envelope                       = $dom->createElement('soap:Envelope');
            $header                         = $dom->createElement('soap:Header');
            $replyTo                        = $dom->createElement('wsa:ReplyTo');
            $wsseSecurity                   = $dom->createElement('wsse:Security');
            $wsuTimestamp                   = $dom->createElement('wsu:Timestamp');
            $wsseUsernameToken              = $dom->createElement('wsse:UsernameToken');
            $TalismaSessionkey              = $dom->createElement('TalismaSessionkey');
            $wsa                            = $dom->createElement('wsa:Action', 'http://www.talisma.com/ResolveObjectForProperties');
            $wsaMessageID                   = $dom->createElement('wsa:MessageID', 'urn:uuidw21s210db3ec-f888-4971-9999-1dw8s745w1ed9f88');
            $wsaAddress                     = $dom->createElement('wsa:Address', 'http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous');
            $wsaTo                          = $dom->createElement('wsa:To', 'http://IP/utilsiservice/Utilssvc.asmx');
            $wsuCreated                     = $dom->createElement('wsu:Created', $tm_created);
            $wsuExpires                     = $dom->createElement('wsu:Expires', $tm_expires);
            $wsseUsername                   = $dom->createElement('wsse:Username', 'username...');
            $wsseNonce                      = $dom->createElement('wsse:Nonce', 'crTDTGVEppXvYj7PacS+HQ=='); # setthis nonce of your web service
            $wssePassword                   = $dom->createElement('wsse:Password', 'password...');
            // * TAGS  BODY                      
            $soapBody                       = $dom->createElement('soap:Body');
            $ResolveObjectForProperties     = $dom->createElement('ResolveObjectForProperties');
            //$inMessage                        = $dom->createElement('ResolveObjectForProperties');     
            $objectType                     = $dom->createElement('objectType', $VObjectType);
            $strPropertyString              = $dom->createElement('strPropertyString',$VPropertyString.'±');    
    
    
    
            // *  setAttribute('PREFIX','LINK') INSERE UM PREFIXO NAMESPACE NA TAG
            $envelope->setAttribute('xmlns:soap', 'http://schemas.xmlsoap.org/soap/envelope/');
            $envelope->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
            $envelope->setAttribute('xmlns:xsd', 'http://www.w3.org/2001/XMLSchema');
            $envelope->setAttribute('xmlns:wsa', 'http://schemas.xmlsoap.org/ws/2004/08/addressing');
            $envelope->setAttribute('xmlns:wsse','http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd');
            $envelope->setAttribute('xmlns:wsu', 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd');
            $wsseSecurity->setAttribute('soap:mustUnderstand', '1');
            $wsuTimestamp->setAttribute('wsu:Id', 'Timestamp-6415016e-9d0c-4c09-8832-cf3ba84d18af');
            $wsseUsernameToken->setAttribute('xmlns:wsu', 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd');
            $wsseUsernameToken->setAttribute('wsu:Id', 'SecurityToken-4f60806e-c940-45d2-a82f-9c654fcefd13');
            $wssePassword->setAttribute('Type', 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText');
    
    
            $ResolveObjectForProperties->setAttribute('xmlns', 'http://www.talisma.com/');
    
            # CRIA A ESTRTURA DO XML
            $envelope->appendChild($header);
            $header->appendChild($wsa);
            $header->appendChild($wsaMessageID);
            $header->appendChild($replyTo);
            $replyTo->appendChild($wsaAddress);
            $header->appendChild($replyTo);
            $header->appendChild($wsaTo);
            $header->appendChild($wsseSecurity);
            $wsseSecurity->appendChild($wsuTimestamp);
            $wsuTimestamp->appendChild($wsuCreated);
            $wsuTimestamp->appendChild($wsuExpires);
            $wsseSecurity->appendChild($wsseUsernameToken);
            $wsseUsernameToken->appendChild($wsseUsername);
            $wsseUsernameToken->appendChild($wsseNonce);
            $wsseUsernameToken->appendChild($wssePassword);
            $wsseUsernameToken->appendChild($TalismaSessionkey);
            $envelope->appendChild($soapBody);
            $soapBody->appendChild($ResolveObjectForProperties);
            $ResolveObjectForProperties->appendChild($objectType);
            $ResolveObjectForProperties->appendChild($strPropertyString);
            //$inMessage->appendChild($objectType);
            //$inMessage->appendChild($strPropertyString);
            $dom->appendChild($envelope); 
            // * SALVA O OBJETO XML CRIADO NA VARIAVEL XML
            $xml = $dom->saveXML($dom->documentElement);
            
            //dd($xml);
            // * POST REQUEST WHITH TEXT XML 
            $ch = curl_init();      
            $URL = ''; # Your service .asxm (http://IP/utilsiservice/Utilssvc.asmx)
            //ignore_user_abort(true);
            set_time_limit(0);
            curl_setopt($ch, CURLOPT_URL,$URL);
            curl_setopt($ch, CURLOPT_VERBOSE, 1);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);                
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
            curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);     

            
            if (curl_errno($ch)) 
            {
                // * ERRO NA REQUISIÇÃO
                $response = curl_errno($ch);        
            } 
            else 
            {           
                // * SALVA O RETORNO DO WEB SERVICE E FECHA O CURL
                $response = curl_exec($ch);
                curl_close($ch);

            }
            
    
            //* RECUPERA OS MULTIPLOS NAMES SPACES E CONVERTE A RESPOSTA XML EM JSON 
            $xml_str = str_replace(PHP_EOL, '', $response);
            $xml     = simplexml_load_string($response,'SimpleXMLElement', LIBXML_NOCDATA);
            $j_obj   = json_encode($xml->xpath('//soap:Body/*'));   
            
            // * CONVERTE O OBJETO JSON PARA ARRAY
            $response = json_decode($j_obj);
            
            // * retorna o "-1 SE O  OBJETO NÃO EXISTIR E "0" SE EXISTIR
            return $response[0]->contactId;

        
    } catch (\Exeption $e) {
            

            #ERROR
            $data  = date("Y-m-d-H-i-s");


    }

        
}

`

I couldn't find any other way to make that connection.
is working well for me this code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment