1 year ago
#173793
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