1 year ago

#173793

test-img

Inèlic

Adding WSSE security headers to PHP's SoapServer Response, using robrichards/wse-php

I am trying to add WSSE Security headers to a SOAP XML message that is created from PHP's SoapServer::handle(). This should be done using SoapServer::addSoapHeaders(new SoapHeaders(...)), but I am unsure how to set specific WSSE security headers to the response by using robrichards/wse-php package.

Firstly the SoapServer is created. Then the incoming request gets handled, which return some stdClass with data that the handle() function presumably automatically converts to a XML SOAP envelope. This is wrapped in Laravel's Illuminate\Http\Response object and returned.

ini_set('soap.wsdl_cache_enabled', 0);
ini_set('soap.wsdl_cache_ttl', 0);
ini_set('default_socket_timeout', 80);
header("Connection: close");

$soap = $this->createSoapServer();

ob_start();

// Response automatically becomes a XML, because of soap->handle() from PHP's SoapServer.
$response = new Response($soap->handle($xml_request), 200);
$response->header('Content-Type', 'text/xml');

return $response;

Within the createSoapServer() function I create a SoapServer and want to add WSSE Security headers to the SoapServer using addSoapHeaders(). The headers I need to add are all present withing an empty soap envelope in the headers_xml variable $headers_xml = $objWSSE->saveXML();. I don't know how to get these headers separately.

I wish to know how to add these headers to the XML response created by the SoapServer. I should be able to add them using addSoapHeaders(), though I do not know how.

private function createSoapServer($soap_settings = []) {

    $soap_settings = $this->assembleSoapSettings($soap_settings);
    $wsdl_path = $soap_settings['wsdl_path'];
    
    // Set soap's own options
    $soap_settings['soap_options'] = array_merge([
        WSDL_CACHE_NONE,
        SOAP_SINGLE_ELEMENT_ARRAYS,
        
        'trace'             => !$this->isProduction, 
        'exceptions'        => true, 
        'cache_wsdl'        => WSDL_CACHE_NONE,
        'use'               => SOAP_LITERAL,
        'connection_timeout' => 80,  
        'soap_version' => SOAP_1_2,

    ], $soap_settings['soap_options']);

    $soap = new SoapServer($wsdl_path, 
        array_merge([
            'location'      => $soap_settings['soap_location'],
            'local_cert'    => $soap_settings['ssl_cert_path'],
            'passphrase'    => $soap_settings['ssl_cert_password'],

        ], $soap_settings['soap_options'])
    );


    // Sets the server php class where the incoming request gets handled.
    $soap->setClass($service_server);

    // Retrieve empty XML envenlope to set headers in. 
    // NOTICE: This is not the correct approach, 
    $request = file_get_contents(app_path('Connect/Register/empty_soap.xml'));
    $options = $this->soapclient_options;

    $dom = new DOMDocument('1.0');
    $dom->loadXML($request);
    $objWSA = new WSASoap($dom, WSASoap::WSANS_2005);
    Log::channel('soap-response')->info("Hit 3");


    /** Add Addressing */
    $objWSA->addFrom($options['wsa_addressing_from']);
    $objWSA->addTo($options['wsa_addressing_to']);
    $objWSA->addAction($options['wsaAction']);
    
    /** Set needed soap header settings */
    $objWSA->addMessageID();
    $dom = $objWSA->getDoc();

    /* Sign all headers to include signing the WS-Addressing headers */
    $objWSSE = new WSSESoap($dom);
    $objWSSE->signAllHeaders = true;
    $objWSSE->addTimestamp();

    /* create new XMLSec Key using RSA SHA256 and type is private key */
    $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, array('type' => 'private'));

    /* load the private key from file*/
    if (isset($options['ssl_private_key_passphrase'])) {
        $objKey->passphrase = $options['ssl_private_key_passphrase'];
    }

    $objKey->loadKey($options['ssl_private_key_path'], true); 

    /* Sign the message - also signs appropraite WS-Security items */
    $objWSSE->signSoapDoc($objKey, 
        [
            'algorithm' => XMLSecurityDSig::SHA256,
            'insertBefore' => false,
        ]
    );

    /* Add certificate (BinarySecurityToken) to the message and attach pointer to Signature */
    $token = $objWSSE->addBinaryToken(file_get_contents($options['ssl_cert_path']));  
    $objWSSE->attachTokentoSig($token);


    /** NOTICE: Problem here! How to get correct type of headers to put into 'addSoapHeaders' of PHP's SoapServer */
    $headers_xml = $objWSSE->saveXML();

    $soap->addSoapHeaders(new SoapHeader("ns", $headers_xml, "value"));


    return $soap;
}

(Please tell if this question is badly formatted or missing information, as this is my first time writing.)

php

laravel

soap

wsse

0 Answers

Your Answer

Accepted video resources