diff --git a/.travis.yml b/.travis.yml
index ae6788a..5150a12 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,6 +14,8 @@ env:
before_script:
- composer require symfony/http-foundation:${SYMFONY_VERSION} --no-interaction --prefer-source
+ - ./src/BeSimple/SoapClient/Tests/bin/phpwebserver.sh
+ - ./src/BeSimple/SoapClient/Tests/bin/axis.sh
script:
- phpunit --coverage-text
diff --git a/src/BeSimple/SoapClient/Curl.php b/src/BeSimple/SoapClient/Curl.php
index 54e40cf..699e56c 100644
--- a/src/BeSimple/SoapClient/Curl.php
+++ b/src/BeSimple/SoapClient/Curl.php
@@ -128,7 +128,7 @@ class Curl
curl_setopt($this->ch, CURLOPT_HTTPHEADER, $requestHeaders);
}
- $this->response = $this->execManualRedirect($this->followLocationMaxRedirects);
+ $this->response = $this->execManualRedirect();
return ($this->response === false) ? false : true;
}
diff --git a/src/BeSimple/SoapClient/SoapClient.php b/src/BeSimple/SoapClient/SoapClient.php
index d0d99e8..5476488 100644
--- a/src/BeSimple/SoapClient/SoapClient.php
+++ b/src/BeSimple/SoapClient/SoapClient.php
@@ -15,6 +15,7 @@ namespace BeSimple\SoapClient;
use BeSimple\SoapCommon\Helper;
use BeSimple\SoapCommon\Converter\MtomTypeConverter;
use BeSimple\SoapCommon\Converter\SwaTypeConverter;
+use BeSimple\SoapCommon\SoapMessage;
/**
* Extended SoapClient that uses a a cURL wrapper for all underlying HTTP
@@ -40,6 +41,15 @@ class SoapClient extends \SoapClient
*/
protected $tracingEnabled = false;
+ /**
+ * Work around missing header/php://input access in PHP cli webserver by
+ * setting headers additionally as GET parameters and SOAP request body
+ * explicitly as POST variable.
+ *
+ * @var boolean
+ */
+ private $cliWebserverWorkaround = false;
+
/**
* cURL instance.
*
@@ -98,6 +108,10 @@ class SoapClient extends \SoapClient
if (isset($options['soap_version'])) {
$this->soapVersion = $options['soap_version'];
}
+ // activate cli webserver workaround
+ if (isset($options['cli_webserver_workaround'])) {
+ $this->cliWebserverWorkaround = $options['cli_webserver_workaround'];
+ }
$this->curl = new Curl($options);
$wsdlFile = $this->loadWsdl($wsdl, $options);
// TODO $wsdlHandler = new WsdlHandler($wsdlFile, $this->soapVersion);
@@ -124,14 +138,45 @@ class SoapClient extends \SoapClient
private function __doHttpRequest(SoapRequest $soapRequest)
{
// HTTP headers
- $headers = array(
- 'Content-Type:' . $soapRequest->getContentType(),
- 'SOAPAction: "' . $soapRequest->getAction() . '"',
- );
+ $soapVersion = $soapRequest->getVersion();
+ $soapAction = $soapRequest->getAction();
+ if (SOAP_1_1 == $soapVersion) {
+ $headers = array(
+ 'Content-Type:' . $soapRequest->getContentType(),
+ 'SOAPAction: "' . $soapAction . '"',
+ );
+ } else {
+ $headers = array(
+ 'Content-Type:' . $soapRequest->getContentType() . '; action="' . $soapAction . '"',
+ );
+ }
+
+ $location = $soapRequest->getLocation();
+ $content = $soapRequest->getContent();
+ /*
+ * Work around missing header/php://input access in PHP cli webserver by
+ * setting headers additionally as GET parameters and SOAP request body
+ * explicitly as POST variable
+ */
+ if ($this->cliWebserverWorkaround === true) {
+ if (strpos($location, '?') === false) {
+ $location .= '?';
+ } else {
+ $location .= '&';
+ }
+ $location .= SoapMessage::CONTENT_TYPE_HEADER.'='.urlencode($soapRequest->getContentType());
+ $location .= '&';
+ $location .= SoapMessage::SOAP_ACTION_HEADER.'='.urlencode($soapRequest->getAction());
+
+ $content = http_build_query(array('request' => $content));
+
+ $headers = array();
+ }
+
// execute HTTP request with cURL
$responseSuccessfull = $this->curl->exec(
- $soapRequest->getLocation(),
- $soapRequest->getContent(),
+ $location,
+ $content,
$headers
);
// tracing enabled: store last request header and body
diff --git a/src/BeSimple/SoapClient/Tests/AxisInterop/Fixtures/AttachmentRequest.php b/src/BeSimple/SoapClient/Tests/AxisInterop/Fixtures/AttachmentRequest.php
new file mode 100644
index 0000000..e4f0236
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/AxisInterop/Fixtures/AttachmentRequest.php
@@ -0,0 +1,7 @@
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BeSimple/SoapClient/Tests/AxisInterop/SwA.wsdl b/src/BeSimple/SoapClient/Tests/AxisInterop/Fixtures/SwA.wsdl
similarity index 98%
rename from src/BeSimple/SoapClient/Tests/AxisInterop/SwA.wsdl
rename to src/BeSimple/SoapClient/Tests/AxisInterop/Fixtures/SwA.wsdl
index a4de7e0..d63fe2d 100644
--- a/src/BeSimple/SoapClient/Tests/AxisInterop/SwA.wsdl
+++ b/src/BeSimple/SoapClient/Tests/AxisInterop/Fixtures/SwA.wsdl
@@ -1,162 +1,162 @@
-
-
- BeSimpleSwaService
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+ BeSimpleSwaService
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BeSimple/SoapClient/Tests/AxisInterop/WsSecuritySigEnc.wsdl b/src/BeSimple/SoapClient/Tests/AxisInterop/Fixtures/WsSecuritySigEnc.wsdl
similarity index 100%
rename from src/BeSimple/SoapClient/Tests/AxisInterop/WsSecuritySigEnc.wsdl
rename to src/BeSimple/SoapClient/Tests/AxisInterop/Fixtures/WsSecuritySigEnc.wsdl
diff --git a/src/BeSimple/SoapClient/Tests/AxisInterop/WsSecurityUserPass.wsdl b/src/BeSimple/SoapClient/Tests/AxisInterop/Fixtures/WsSecurityUserPass.wsdl
similarity index 100%
rename from src/BeSimple/SoapClient/Tests/AxisInterop/WsSecurityUserPass.wsdl
rename to src/BeSimple/SoapClient/Tests/AxisInterop/Fixtures/WsSecurityUserPass.wsdl
diff --git a/src/BeSimple/SoapClient/Tests/AxisInterop/Fixtures/addBook.php b/src/BeSimple/SoapClient/Tests/AxisInterop/Fixtures/addBook.php
new file mode 100644
index 0000000..7a171b0
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/AxisInterop/Fixtures/addBook.php
@@ -0,0 +1,11 @@
+ SOAP_1_1,
- 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
- 'trace' => true, // enables use of the methods SoapClient->__getLastRequest, SoapClient->__getLastRequestHeaders, SoapClient->__getLastResponse and SoapClient->__getLastResponseHeaders
- 'attachment_type' => BeSimpleSoapHelper::ATTACHMENTS_TYPE_MTOM,
- 'cache_wsdl' => WSDL_CACHE_NONE,
- 'classmap' => array(
- 'base64Binary' => 'base64Binary',
- 'AttachmentRequest' => 'AttachmentRequest',
- ),
-);
-
-/*
- * Deploy "axis_services/sample-mtom.aar" to Apache Axis2 to get this
- * example to work.
- *
- * Apache Axis2 MTOM example.
- *
- */
-$sc = new BeSimpleSoapClient('MTOM.wsdl', $options);
-
-//var_dump($sc->__getFunctions());
-//var_dump($sc->__getTypes());
-
-try {
- $b64 = new base64Binary();
- $b64->_ = 'This is a test. :)';
- $b64->contentType = 'text/plain';
-
- $attachment = new AttachmentRequest();
- $attachment->fileName = 'test123.txt';
- $attachment->binaryData = $b64;
-
- var_dump($sc->attachment($attachment));
-
-} catch (Exception $e) {
- var_dump($e);
-}
-
-// var_dump(
-// $sc->__getLastRequestHeaders(),
-// $sc->__getLastRequest(),
-// $sc->__getLastResponseHeaders(),
-// $sc->__getLastResponse()
-// );
\ No newline at end of file
diff --git a/src/BeSimple/SoapClient/Tests/AxisInterop/MtomAxisInteropTest.php b/src/BeSimple/SoapClient/Tests/AxisInterop/MtomAxisInteropTest.php
new file mode 100644
index 0000000..27d9e20
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/AxisInterop/MtomAxisInteropTest.php
@@ -0,0 +1,51 @@
+ SOAP_1_1,
+ 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
+ 'attachment_type' => BeSimpleSoapHelper::ATTACHMENTS_TYPE_MTOM,
+ 'cache_wsdl' => WSDL_CACHE_NONE,
+ 'classmap' => array(
+ 'base64Binary' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\base64Binary',
+ 'AttachmentRequest' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\AttachmentRequest',
+ ),
+ );
+
+ public function testAttachment()
+ {
+ $sc = new BeSimpleSoapClient(__DIR__.'/Fixtures/MTOM.wsdl', $this->options);
+
+ $b64 = new base64Binary();
+ $b64->_ = 'This is a test. :)';
+ $b64->contentType = 'text/plain';
+
+ $attachment = new AttachmentRequest();
+ $attachment->fileName = 'test123.txt';
+ $attachment->binaryData = $b64;
+
+ $this->assertEquals('File saved succesfully.', $sc->attachment($attachment));
+
+// $fileCreatedByServer = __DIR__.'/'.$attachment->fileName;
+// $this->assertEquals($b64->_, file_get_contents($fileCreatedByServer));
+// unlink($fileCreatedByServer);
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapClient/Tests/AxisInterop/SwA.php b/src/BeSimple/SoapClient/Tests/AxisInterop/SwA.php
deleted file mode 100644
index eaf1bc6..0000000
--- a/src/BeSimple/SoapClient/Tests/AxisInterop/SwA.php
+++ /dev/null
@@ -1,84 +0,0 @@
- SOAP_1_1,
- 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
- 'trace' => true, // enables use of the methods SoapClient->__getLastRequest, SoapClient->__getLastRequestHeaders, SoapClient->__getLastResponse and SoapClient->__getLastResponseHeaders
- 'attachment_type' => BeSimpleSoapHelper::ATTACHMENTS_TYPE_SWA,
- 'cache_wsdl' => WSDL_CACHE_NONE,
-);
-
-/*
- * Deploy "axis_services/besimple-swa.aar" to Apache Axis2 to get this
- * example to work.
- *
- * Run ant to rebuild aar.
- *
- * Example based on:
- * http://axis.apache.org/axis2/java/core/docs/mtom-guide.html#a3
- * http://wso2.org/library/1675
- *
- * Doesn't work directly with ?wsdl served by Apache Axis!
- *
- */
-
-$sc = new BeSimpleSoapClient('SwA.wsdl', $options);
-
-//var_dump($sc->__getFunctions());
-//var_dump($sc->__getTypes());
-
-try {
- $file = new stdClass();
- $file->name = 'upload.txt';
- $file->data = 'This is a test text!';
- $result = $sc->uploadFile($file);
-
- var_dump(
- $result->return
- );
-
- $file = new stdClass();
- $file->name = 'upload.txt';
- $result = $sc->downloadFile($file);
-
- var_dump(
- $result->data
- );
-
- $file = new stdClass();
- $file->name = 'image.jpg'; // source: http://www.freeimageslive.com/galleries/light/pics/swirl3768.jpg
- $file->data = file_get_contents('image.jpg');
- $result = $sc->uploadFile($file);
-
- var_dump(
- $result->return
- );
-
- $crc32 = crc32($file->data);
-
- $file = new stdClass();
- $file->name = 'image.jpg';
- $result = $sc->downloadFile($file);
-
- file_put_contents('image2.jpg', $result->data);
-
-
- var_dump(
- crc32($result->data) === $crc32
- );
-
-} catch (Exception $e) {
- var_dump($e);
-}
-
-// var_dump(
-// $sc->__getLastRequestHeaders(),
-// $sc->__getLastRequest(),
-// $sc->__getLastResponseHeaders(),
-// $sc->__getLastResponse()
-// );
\ No newline at end of file
diff --git a/src/BeSimple/SoapClient/Tests/AxisInterop/SwA/build.xml b/src/BeSimple/SoapClient/Tests/AxisInterop/SwA/build.xml
index f5261ed..836bda8 100644
--- a/src/BeSimple/SoapClient/Tests/AxisInterop/SwA/build.xml
+++ b/src/BeSimple/SoapClient/Tests/AxisInterop/SwA/build.xml
@@ -1,38 +1,38 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BeSimple/SoapClient/Tests/AxisInterop/SwA/resources/META-INF/services.xml b/src/BeSimple/SoapClient/Tests/AxisInterop/SwA/resources/META-INF/services.xml
index 8b49f87..8bac2eb 100644
--- a/src/BeSimple/SoapClient/Tests/AxisInterop/SwA/resources/META-INF/services.xml
+++ b/src/BeSimple/SoapClient/Tests/AxisInterop/SwA/resources/META-INF/services.xml
@@ -1,15 +1,15 @@
-
-
+
+
BeSimple test service for SwA.
- true
- besimple.service.BeSimpleSwaService
-
- urn:uploadFile
-
-
-
- urn:downloadFile
-
-
-
-
+ true
+ besimple.service.BeSimpleSwaService
+
+ urn:uploadFile
+
+
+
+ urn:downloadFile
+
+
+
+
diff --git a/src/BeSimple/SoapClient/Tests/AxisInterop/SwaAxisInteropTest.php b/src/BeSimple/SoapClient/Tests/AxisInterop/SwaAxisInteropTest.php
new file mode 100644
index 0000000..4b9921f
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/AxisInterop/SwaAxisInteropTest.php
@@ -0,0 +1,77 @@
+ SOAP_1_1,
+ 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
+ 'attachment_type' => BeSimpleSoapHelper::ATTACHMENTS_TYPE_SWA,
+ 'cache_wsdl' => WSDL_CACHE_NONE,
+ 'classmap' => array(
+ 'downloadFile' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\downloadFile',
+ 'downloadFileResponse' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\downloadFileResponse',
+ 'uploadFile' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\uploadFile',
+ 'uploadFileResponse' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\uploadFileResponse',
+ ),
+ );
+
+ public function testUploadDownloadText()
+ {
+ $sc = new BeSimpleSoapClient(__DIR__.'/Fixtures/SwA.wsdl', $this->options);
+
+ $upload = new uploadFile();
+ $upload->name = 'upload.txt';
+ $upload->data = 'This is a test. :)';
+ $result = $sc->uploadFile($upload);
+
+ $this->assertEquals('File saved succesfully.', $result->return);
+
+ $download = new downloadFile();
+ $download->name = 'upload.txt';
+ $result = $sc->downloadFile($download);
+
+ $this->assertEquals($upload->data, $result->data);
+ }
+
+ public function testUploadDownloadImage()
+ {
+ $sc = new BeSimpleSoapClient(__DIR__.'/Fixtures/SwA.wsdl', $this->options);
+
+ $upload = new uploadFile();
+ $upload->name = 'image.jpg';
+ $upload->data = file_get_contents(__DIR__.'/Fixtures/image.jpg'); // source: http://www.freeimageslive.com/galleries/light/pics/swirl3768.jpg;
+ $result = $sc->uploadFile($upload);
+
+ $this->assertEquals('File saved succesfully.', $result->return);
+
+ $download = new downloadFile();
+ $download->name = 'image.jpg';
+ $result = $sc->downloadFile($download);
+
+ $this->assertEquals($upload->data, $result->data);
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapClient/Tests/AxisInterop/TestCase.php b/src/BeSimple/SoapClient/Tests/AxisInterop/TestCase.php
new file mode 100644
index 0000000..eb57435
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/AxisInterop/TestCase.php
@@ -0,0 +1,23 @@
+markTestSkipped(
+ 'The Axis server is not started on port 8080.'
+ );
+ }
+
+ curl_close($ch);
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapClient/Tests/AxisInterop/WsAddressing.php b/src/BeSimple/SoapClient/Tests/AxisInterop/WsAddressing.php
deleted file mode 100644
index dacabcb..0000000
--- a/src/BeSimple/SoapClient/Tests/AxisInterop/WsAddressing.php
+++ /dev/null
@@ -1,73 +0,0 @@
- SOAP_1_2,
- 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
- 'trace' => true, // enables use of the methods SoapClient->__getLastRequest, SoapClient->__getLastRequestHeaders, SoapClient->__getLastResponse and SoapClient->__getLastResponseHeaders
-);
-
-/*
- * Deploy "axis_services/version2.aar" to Apache Axis2 to get this example to
- * work.
- *
- * To rebuild the "axis_services/version2.aar" the following steps need to be
- * done to build a working Apache Axis2 version service with SOAP session
- * enabled.
- *
- * 1) Go to $AXIS_HOME/samples/version and edit the following files:
- *
- * resources/META-INF/services.xml:
- *
- * ...
- *
- *
- * build.xml:
- * replace version.aar with version2.aar
- *
- * 2) Run ant build.xml in "$AXIS_HOME/samples/version"
- *
- */
-
-$sc = new BeSimpleSoapClient('http://localhost:8080/axis2/services/Version2?wsdl', $options);
-$soapKernel = $sc->getSoapKernel();
-$wsaFilter = new BeSimpleWsAddressingFilter();
-$soapKernel->registerFilter($wsaFilter);
-
-//var_dump($sc->__getFunctions());
-//var_dump($sc->__getTypes());
-
-try {
- $wsaFilter->setReplyTo(BeSimpleWsAddressingFilter::ENDPOINT_REFERENCE_ANONYMOUS);
- $wsaFilter->setMessageId();
-
- var_dump($sc->getVersion());
-
- $soapSessionId1 = $wsaFilter->getReferenceParameter('http://ws.apache.org/namespaces/axis2', 'ServiceGroupId');
- echo 'ID1: ' .$soapSessionId1 . PHP_EOL;
-
- $wsaFilter->addReferenceParameter('http://ws.apache.org/namespaces/axis2', 'axis2', 'ServiceGroupId', $soapSessionId1);
-
- var_dump($sc->getVersion());
-
- $soapSessionId2 = $wsaFilter->getReferenceParameter('http://ws.apache.org/namespaces/axis2', 'ServiceGroupId');
- echo 'ID2: ' . $soapSessionId2 . PHP_EOL;
-
- if ($soapSessionId1 == $soapSessionId2) {
- echo PHP_EOL;
- echo 'SOAP session worked :)';
- }
-} catch (Exception $e) {
- var_dump($e);
-}
-
-// var_dump(
-// $sc->__getLastRequestHeaders(),
-// $sc->__getLastRequest(),
-// $sc->__getLastResponseHeaders(),
-// $sc->__getLastResponse()
-// );
\ No newline at end of file
diff --git a/src/BeSimple/SoapClient/Tests/AxisInterop/WsAddressingAxisInteropTest.php b/src/BeSimple/SoapClient/Tests/AxisInterop/WsAddressingAxisInteropTest.php
new file mode 100644
index 0000000..cf7308a
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/AxisInterop/WsAddressingAxisInteropTest.php
@@ -0,0 +1,59 @@
+
+ * ...
+ *
+ *
+ * build.xml:
+ * replace version.aar with version2.aar
+ *
+ * 2) Run ant build.xml in "$AXIS_HOME/samples/version"
+ *
+ */
+
+use BeSimple\SoapClient\SoapClient as BeSimpleSoapClient;
+use BeSimple\SoapClient\WsAddressingFilter as BeSimpleWsAddressingFilter;
+
+use BeSimple\SoapClient\Tests\AxisInterop\TestCase;
+
+class WsAddressingAxisInteropTest extends TestCase
+{
+ private $options = array(
+ 'soap_version' => SOAP_1_2,
+ 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
+ );
+
+ public function testSession()
+ {
+ $sc = new BeSimpleSoapClient('http://localhost:8080/axis2/services/Version2?wsdl', $this->options);
+ $soapKernel = $sc->getSoapKernel();
+ $wsaFilter = new BeSimpleWsAddressingFilter();
+ $soapKernel->registerFilter($wsaFilter);
+
+ $wsaFilter->setReplyTo(BeSimpleWsAddressingFilter::ENDPOINT_REFERENCE_ANONYMOUS);
+ $wsaFilter->setMessageId();
+
+ $version = $sc->getVersion();
+
+ $soapSessionId1 = $wsaFilter->getReferenceParameter('http://ws.apache.org/namespaces/axis2', 'ServiceGroupId');
+
+ $wsaFilter->addReferenceParameter('http://ws.apache.org/namespaces/axis2', 'axis2', 'ServiceGroupId', $soapSessionId1);
+
+ $version = $sc->getVersion();
+
+ $soapSessionId2 = $wsaFilter->getReferenceParameter('http://ws.apache.org/namespaces/axis2', 'ServiceGroupId');
+
+ $this->assertEquals($soapSessionId1, $soapSessionId2);
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapClient/Tests/AxisInterop/WsSecuritySigEnc.php b/src/BeSimple/SoapClient/Tests/AxisInterop/WsSecuritySigEnc.php
deleted file mode 100644
index d6a31fb..0000000
--- a/src/BeSimple/SoapClient/Tests/AxisInterop/WsSecuritySigEnc.php
+++ /dev/null
@@ -1,116 +0,0 @@
-';
-
-$options = array(
- 'soap_version' => SOAP_1_2,
- 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
- 'trace' => true, // enables use of the methods SoapClient->__getLastRequest, SoapClient->__getLastRequestHeaders, SoapClient->__getLastResponse and SoapClient->__getLastResponseHeaders
-);
-
-/*
- * Deploy "axis_services/library-signencr.aar" to Apache Axis2 to get this
- * example to work.
- *
- * Links:
- * http://www.dcc.uchile.cl/~pcamacho/tutorial/web/xmlsec/xmlsec.html
- * http://www.aleksey.com/xmlsec/xmldsig-verifier.html
- *
- * Using code from axis example:
- * http://www.ibm.com/developerworks/java/library/j-jws5/index.html
- *
- * Download key tool to export private key
- * http://couchpotato.net/pkeytool/
- *
- * keytool -export -alias serverkey -keystore server.keystore -storepass nosecret -file servercert.cer
- * openssl x509 -out servercert.pem -outform pem -in servercert.pem -inform der
- *
- * keytool -export -alias clientkey -keystore client.keystore -storepass nosecret -file clientcert.cer
- * openssl x509 -out clientcert.pem -outform pem -in clientcert.pem -inform der
- * java -jar pkeytool.jar -exportkey -keystore client.keystore -storepass nosecret -keypass clientpass -rfc -alias clientkey -file clientkey.pem
- *
- * C:\Program Files\Java\jre6\bin\keytool -export -alias serverkey -keystore server.keystore -storepass nosecret -file servercert.cer
- * C:\xampp\apache\bin\openssl x509 -out servercert.pem -outform pem -in servercert.cer -inform der
- *
- * C:\Program Files\Java\jre6\bin\keytool -export -alias clientkey -keystore client.keystore -storepass nosecret -file clientcert.cer
- * C:\xampp\apache\bin\openssl x509 -out clientcert.pem -outform pem -in clientcert.cer -inform der
- * java -jar C:\axis2\pkeytool\pkeytool.jar -exportkey -keystore client.keystore -storepass nosecret -keypass clientpass -rfc -alias clientkey -file clientkey.pem
- *
- * build.properties:
- * server-policy=hash-policy-server.xml
- *
- * allows both text and digest!
- */
-
-class getBook {}
-class getBookResponse {}
-class getBooksByType {}
-class getBooksByTypeResponse {}
-class addBook {}
-class addBookResponse {}
-class BookInformation {}
-
-$options['classmap'] = array(
- 'getBook' => 'getBook',
- 'getBookResponse' => 'getBookResponse',
- 'getBooksByType' => 'getBooksByType',
- 'getBooksByTypeResponse' => 'getBooksByTypeResponse',
- 'addBook' => 'addBook',
- 'addBookResponse' => 'addBookResponse',
- 'BookInformation' => 'BookInformation',
-);
-
-$sc = new BeSimpleSoapClient('WsSecuritySigEnc.wsdl', $options);
-
-$wssFilter = new BeSimpleWsSecurityFilter();
-// user key for signature and encryption
-$securityKeyUser = new BeSimpleWsSecurityKey();
-$securityKeyUser->addPrivateKey(XmlSecurityKey::RSA_SHA1, 'clientkey.pem', true);
-$securityKeyUser->addPublicKey(XmlSecurityKey::RSA_SHA1, 'clientcert.pem', true);
-$wssFilter->setUserSecurityKeyObject($securityKeyUser);
-// service key for encryption
-$securityKeyService = new BeSimpleWsSecurityKey();
-$securityKeyService->addPrivateKey(XmlSecurityKey::TRIPLEDES_CBC);
-$securityKeyService->addPublicKey(XmlSecurityKey::RSA_1_5, 'servercert.pem', true);
-$wssFilter->setServiceSecurityKeyObject($securityKeyService);
-// TOKEN_REFERENCE_SUBJECT_KEY_IDENTIFIER | TOKEN_REFERENCE_SECURITY_TOKEN | TOKEN_REFERENCE_THUMBPRINT_SHA1
-$wssFilter->setSecurityOptionsSignature(BeSimpleWsSecurityFilter::TOKEN_REFERENCE_SECURITY_TOKEN);
-$wssFilter->setSecurityOptionsEncryption(BeSimpleWsSecurityFilter::TOKEN_REFERENCE_THUMBPRINT_SHA1);
-
-$soapKernel = $sc->getSoapKernel();
-$soapKernel->registerFilter($wssFilter);
-
-//var_dump($sc->__getFunctions());
-//var_dump($sc->__getTypes());
-
-try {
- $gb = new getBook();
- $gb->isbn = '0061020052';
- var_dump($sc->getBook($gb));
-
- $ab = new addBook();
- $ab->isbn = '0445203498';
- $ab->title = 'The Dragon Never Sleeps';
- $ab->author = 'Cook, Glen';
- $ab->type = 'scifi';
- var_dump($sc->addBook($ab));
-
- // getBooksByType("scifi");
-} catch (Exception $e) {
- var_dump($e);
-}
-
-//var_dump(
-// $sc->__getLastRequestHeaders(),
-// $sc->__getLastRequest(),
-// $sc->__getLastResponseHeaders(),
-// $sc->__getLastResponse()
-//);
diff --git a/src/BeSimple/SoapClient/Tests/AxisInterop/WsSecuritySigEncAxisInteropTest.php b/src/BeSimple/SoapClient/Tests/AxisInterop/WsSecuritySigEncAxisInteropTest.php
new file mode 100644
index 0000000..6e4f0d9
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/AxisInterop/WsSecuritySigEncAxisInteropTest.php
@@ -0,0 +1,106 @@
+ SOAP_1_2,
+ 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
+ 'classmap' => array(
+ 'getBook' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\getBook',
+ 'getBookResponse' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\getBookResponse',
+ 'getBooksByType' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\getBooksByType',
+ 'getBooksByTypeResponse' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\getBooksByTypeResponse',
+ 'addBook' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\addBook',
+ 'addBookResponse' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\addBookResponse',
+ 'BookInformation' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\BookInformation',
+ ),
+ );
+
+ public function testSigEnc()
+ {
+ $sc = new BeSimpleSoapClient(__DIR__.'/Fixtures/WsSecuritySigEnc.wsdl', $this->options);
+
+ $wssFilter = new BeSimpleWsSecurityFilter();
+ // user key for signature and encryption
+ $securityKeyUser = new BeSimpleWsSecurityKey();
+ $securityKeyUser->addPrivateKey(XmlSecurityKey::RSA_SHA1, __DIR__.'/Fixtures/clientkey.pem', true);
+ $securityKeyUser->addPublicKey(XmlSecurityKey::RSA_SHA1, __DIR__.'/Fixtures/clientcert.pem', true);
+ $wssFilter->setUserSecurityKeyObject($securityKeyUser);
+ // service key for encryption
+ $securityKeyService = new BeSimpleWsSecurityKey();
+ $securityKeyService->addPrivateKey(XmlSecurityKey::TRIPLEDES_CBC);
+ $securityKeyService->addPublicKey(XmlSecurityKey::RSA_1_5, __DIR__.'/Fixtures/servercert.pem', true);
+ $wssFilter->setServiceSecurityKeyObject($securityKeyService);
+ // TOKEN_REFERENCE_SUBJECT_KEY_IDENTIFIER | TOKEN_REFERENCE_SECURITY_TOKEN | TOKEN_REFERENCE_THUMBPRINT_SHA1
+ $wssFilter->setSecurityOptionsSignature(BeSimpleWsSecurityFilter::TOKEN_REFERENCE_SECURITY_TOKEN);
+ $wssFilter->setSecurityOptionsEncryption(BeSimpleWsSecurityFilter::TOKEN_REFERENCE_THUMBPRINT_SHA1);
+
+ $soapKernel = $sc->getSoapKernel();
+ $soapKernel->registerFilter($wssFilter);
+
+ $gb = new getBook();
+ $gb->isbn = '0061020052';
+ $result = $sc->getBook($gb);
+ $this->assertInstanceOf('BeSimple\SoapClient\Tests\AxisInterop\Fixtures\BookInformation', $result->getBookReturn);
+
+ $ab = new addBook();
+ $ab->isbn = '0445203498';
+ $ab->title = 'The Dragon Never Sleeps';
+ $ab->author = 'Cook, Glen';
+ $ab->type = 'scifi';
+
+ $this->assertTrue((bool) $sc->addBook($ab));
+
+ // getBooksByType("scifi");
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapClient/Tests/AxisInterop/WsSecurityUserPass.php b/src/BeSimple/SoapClient/Tests/AxisInterop/WsSecurityUserPass.php
deleted file mode 100644
index 231f1e5..0000000
--- a/src/BeSimple/SoapClient/Tests/AxisInterop/WsSecurityUserPass.php
+++ /dev/null
@@ -1,79 +0,0 @@
- SOAP_1_2,
- 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
- 'trace' => true, // enables use of the methods SoapClient->__getLastRequest, SoapClient->__getLastRequestHeaders, SoapClient->__getLastResponse and SoapClient->__getLastResponseHeaders
-);
-
-/*
- * Deploy "axis_services/library-username-digest.aar" to Apache Axis2 to get
- * this example to work.
- *
- * Using code from axis example:
- * http://www.ibm.com/developerworks/java/library/j-jws4/index.html
- *
- * build.properties:
- * server-policy=hash-policy-server.xml
- *
- * allows both text and digest!
- */
-
-class getBook {}
-class getBookResponse {}
-class getBooksByType {}
-class getBooksByTypeResponse {}
-class addBook {}
-class addBookResponse {}
-class BookInformation {}
-
-$options['classmap'] = array(
- 'getBook' => 'getBook',
- 'getBookResponse' => 'getBookResponse',
- 'getBooksByType' => 'getBooksByType',
- 'getBooksByTypeResponse' => 'getBooksByTypeResponse',
- 'addBook' => 'addBook',
- 'addBookResponse' => 'addBookResponse',
- 'BookInformation' => 'BookInformation',
-);
-
-$sc = new BeSimpleSoapClient('WsSecurityUserPass.wsdl', $options);
-
-$wssFilter = new BeSimpleWsSecurityFilter(true, 600);
-$wssFilter->addUserData('libuser', 'books', BeSimpleWsSecurityFilter::PASSWORD_TYPE_TEXT);
-//$wssFilter->addUserData( 'libuser', 'books', BeSimpleWsSecurityFilter::PASSWORD_TYPE_DIGEST );
-
-$soapKernel = $sc->getSoapKernel();
-$soapKernel->registerFilter($wssFilter);
-
-//var_dump($sc->__getFunctions());
-//var_dump($sc->__getTypes());
-
-try {
- $gb = new getBook();
- $gb->isbn = '0061020052';
- var_dump($sc->getBook($gb));
-
- $ab = new addBook();
- $ab->isbn = '0445203498';
- $ab->title = 'The Dragon Never Sleeps';
- $ab->author = 'Cook, Glen';
- $ab->type = 'scifi';
- var_dump($sc->addBook($ab));
-
- // getBooksByType("scifi");
-} catch (Exception $e) {
- var_dump($e);
-}
-
-//var_dump(
-// $sc->__getLastRequestHeaders(),
-// $sc->__getLastRequest(),
-// $sc->__getLastResponseHeaders(),
-// $sc->__getLastResponse()
-//);
diff --git a/src/BeSimple/SoapClient/Tests/AxisInterop/WsSecurityUserPassAxisInteropTest.php b/src/BeSimple/SoapClient/Tests/AxisInterop/WsSecurityUserPassAxisInteropTest.php
new file mode 100644
index 0000000..6ab2824
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/AxisInterop/WsSecurityUserPassAxisInteropTest.php
@@ -0,0 +1,96 @@
+ SOAP_1_2,
+ 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
+ 'classmap' => array(
+ 'getBook' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\getBook',
+ 'getBookResponse' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\getBookResponse',
+ 'getBooksByType' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\getBooksByType',
+ 'getBooksByTypeResponse' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\getBooksByTypeResponse',
+ 'addBook' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\addBook',
+ 'addBookResponse' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\addBookResponse',
+ 'BookInformation' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\BookInformation',
+ ),
+ );
+
+ public function testUserPassText()
+ {
+ $sc = new BeSimpleSoapClient(__DIR__.'/Fixtures/WsSecurityUserPass.wsdl', $this->options);
+
+ $wssFilter = new BeSimpleWsSecurityFilter(true, 600);
+ $wssFilter->addUserData('libuser', 'books', BeSimpleWsSecurityFilter::PASSWORD_TYPE_TEXT);
+
+ $soapKernel = $sc->getSoapKernel();
+ $soapKernel->registerFilter($wssFilter);
+
+ $gb = new getBook();
+ $gb->isbn = '0061020052';
+ $result = $sc->getBook($gb);
+ $this->assertInstanceOf('BeSimple\SoapClient\Tests\AxisInterop\Fixtures\BookInformation', $result->getBookReturn);
+
+ $ab = new addBook();
+ $ab->isbn = '0445203498';
+ $ab->title = 'The Dragon Never Sleeps';
+ $ab->author = 'Cook, Glen';
+ $ab->type = 'scifi';
+
+ $this->assertTrue((bool) $sc->addBook($ab));
+
+ // getBooksByType("scifi");
+ }
+
+ public function testUserPassDigest()
+ {
+ $sc = new BeSimpleSoapClient(__DIR__.'/Fixtures/WsSecurityUserPass.wsdl', $this->options);
+
+ $wssFilter = new BeSimpleWsSecurityFilter(true, 600);
+ $wssFilter->addUserData( 'libuser', 'books', BeSimpleWsSecurityFilter::PASSWORD_TYPE_DIGEST );
+
+ $soapKernel = $sc->getSoapKernel();
+ $soapKernel->registerFilter($wssFilter);
+
+ $gb = new getBook();
+ $gb->isbn = '0061020052';
+ $result = $sc->getBook($gb);
+ $this->assertInstanceOf('BeSimple\SoapClient\Tests\AxisInterop\Fixtures\BookInformation', $result->getBookReturn);
+
+ $ab = new addBook();
+ $ab->isbn = '0445203498';
+ $ab->title = 'The Dragon Never Sleeps';
+ $ab->author = 'Cook, Glen';
+ $ab->type = 'scifi';
+
+ $this->assertTrue((bool) $sc->addBook($ab));
+
+ // getBooksByType("scifi");
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapClient/Tests/ServerInterop/Fixtures/AttachmentRequest.php b/src/BeSimple/SoapClient/Tests/ServerInterop/Fixtures/AttachmentRequest.php
new file mode 100644
index 0000000..8be17dc
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/ServerInterop/Fixtures/AttachmentRequest.php
@@ -0,0 +1,7 @@
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BeSimple/SoapClient/Tests/ServerInterop/Fixtures/SwA.wsdl b/src/BeSimple/SoapClient/Tests/ServerInterop/Fixtures/SwA.wsdl
new file mode 100644
index 0000000..46b14b7
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/ServerInterop/Fixtures/SwA.wsdl
@@ -0,0 +1,162 @@
+
+
+ BeSimpleSwaService
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BeSimple/SoapClient/Tests/ServerInterop/Fixtures/WsSecuritySigEnc.wsdl b/src/BeSimple/SoapClient/Tests/ServerInterop/Fixtures/WsSecuritySigEnc.wsdl
new file mode 100644
index 0000000..d329f1f
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/ServerInterop/Fixtures/WsSecuritySigEnc.wsdl
@@ -0,0 +1,184 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BeSimple/SoapClient/Tests/ServerInterop/Fixtures/WsSecurityUserPass.wsdl b/src/BeSimple/SoapClient/Tests/ServerInterop/Fixtures/WsSecurityUserPass.wsdl
new file mode 100644
index 0000000..7d4b33f
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/ServerInterop/Fixtures/WsSecurityUserPass.wsdl
@@ -0,0 +1,184 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BeSimple/SoapClient/Tests/ServerInterop/Fixtures/addBook.php b/src/BeSimple/SoapClient/Tests/ServerInterop/Fixtures/addBook.php
new file mode 100644
index 0000000..8d22133
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/ServerInterop/Fixtures/addBook.php
@@ -0,0 +1,11 @@
+ SOAP_1_1,
@@ -28,12 +15,14 @@ $options = array(
'attachment_type' => BeSimpleSoapHelper::ATTACHMENTS_TYPE_MTOM,
'cache_wsdl' => WSDL_CACHE_NONE,
'classmap' => array(
- 'base64Binary' => 'base64Binary',
- 'AttachmentRequest' => 'AttachmentRequest',
+ 'base64Binary' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\base64Binary',
+ 'AttachmentRequest' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\AttachmentRequest',
),
+ 'cli_webserver_workaround' => true, // Work around missing header access in PHP cli webserver by setting headers additionally as GET parameters.
+ 'connection_timeout' => 1,
);
-$sc = new BeSimpleSoapClient('MTOM.wsdl', $options);
+$sc = new BeSimpleSoapClient('Fixtures/MTOM.wsdl', $options);
//var_dump($sc->__getFunctions());
//var_dump($sc->__getTypes());
diff --git a/src/BeSimple/SoapClient/Tests/ServerInterop/MTOMServer.php b/src/BeSimple/SoapClient/Tests/ServerInterop/MTOMServer.php
index 5deee38..f86bda5 100644
--- a/src/BeSimple/SoapClient/Tests/ServerInterop/MTOMServer.php
+++ b/src/BeSimple/SoapClient/Tests/ServerInterop/MTOMServer.php
@@ -1,25 +1,11 @@
SOAP_1_1,
@@ -27,8 +13,8 @@ $options = array(
'attachment_type' => BeSimpleSoapHelper::ATTACHMENTS_TYPE_MTOM,
'cache_wsdl' => WSDL_CACHE_NONE,
'classmap' => array(
- 'base64Binary' => 'base64Binary',
- 'AttachmentRequest' => 'AttachmentRequest',
+ 'base64Binary' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\base64Binary',
+ 'AttachmentRequest' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\AttachmentRequest',
),
);
@@ -38,16 +24,12 @@ class Mtom
{
$b64 = $attachment->binaryData;
- file_put_contents('test.txt', var_export(array(
- $attachment->fileName,
- $b64->_,
- $b64->contentType
- ), true));
+ file_put_contents(__DIR__.'/'.$attachment->fileName, $b64->_);
- return 'done';
+ return 'File saved succesfully.';
}
}
-$ss = new BeSimpleSoapServer('MTOM.wsdl', $options);
+$ss = new BeSimpleSoapServer(__DIR__.'/Fixtures/MTOM.wsdl', $options);
$ss->setClass('Mtom');
$ss->handle();
diff --git a/src/BeSimple/SoapClient/Tests/ServerInterop/MtomServerInteropTest.php b/src/BeSimple/SoapClient/Tests/ServerInterop/MtomServerInteropTest.php
new file mode 100644
index 0000000..7277bed
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/ServerInterop/MtomServerInteropTest.php
@@ -0,0 +1,44 @@
+ SOAP_1_1,
+ 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
+ 'attachment_type' => BeSimpleSoapHelper::ATTACHMENTS_TYPE_MTOM,
+ 'cache_wsdl' => WSDL_CACHE_NONE,
+ 'classmap' => array(
+ 'base64Binary' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\base64Binary',
+ 'AttachmentRequest' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\AttachmentRequest',
+ ),
+ 'cli_webserver_workaround' => true, // Work around missing header access in PHP cli webserver by setting headers additionally as GET parameters.
+ );
+
+ public function testAttachment()
+ {
+ $sc = new BeSimpleSoapClient(__DIR__.'/Fixtures/MTOM.wsdl', $this->options);
+
+ $b64 = new base64Binary();
+ $b64->_ = 'This is a test. :)';
+ $b64->contentType = 'text/plain';
+
+ $attachment = new AttachmentRequest();
+ $attachment->fileName = 'test123.txt';
+ $attachment->binaryData = $b64;
+
+ $this->assertEquals('File saved succesfully.', $sc->attachment($attachment));
+
+ $fileCreatedByServer = __DIR__.'/'.$attachment->fileName;
+ $this->assertEquals($b64->_, file_get_contents($fileCreatedByServer));
+ unlink($fileCreatedByServer);
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapClient/Tests/ServerInterop/SwAServer.php b/src/BeSimple/SoapClient/Tests/ServerInterop/SwAServer.php
new file mode 100644
index 0000000..337a0a0
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/ServerInterop/SwAServer.php
@@ -0,0 +1,49 @@
+ SOAP_1_1,
+ 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
+ 'attachment_type' => BeSimpleSoapHelper::ATTACHMENTS_TYPE_SWA,
+ 'cache_wsdl' => WSDL_CACHE_NONE,
+ 'classmap' => array(
+ 'downloadFile' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\downloadFile',
+ 'downloadFileResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\downloadFileResponse',
+ 'uploadFile' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\uploadFile',
+ 'uploadFileResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\uploadFileResponse',
+ ),
+);
+
+class SwA
+{
+ public function uploadFile(uploadFile $uploadFile)
+ {
+ file_put_contents(__DIR__.'/'.$uploadFile->name, $uploadFile->data);
+
+ $ufr = new uploadFileResponse();
+ $ufr->return = 'File saved succesfully.';
+
+ return $ufr;
+ }
+
+ public function downloadFile(downloadFile $downloadFile)
+ {
+ $dfr = new downloadFileResponse();
+ $dfr->data = file_get_contents(__DIR__.'/'.$downloadFile->name);
+
+ return $dfr;
+ }
+}
+
+$ss = new BeSimpleSoapServer(__DIR__.'/Fixtures/SwA.wsdl', $options);
+$ss->setClass('SwA');
+$ss->handle();
diff --git a/src/BeSimple/SoapClient/Tests/ServerInterop/SwaClient.php b/src/BeSimple/SoapClient/Tests/ServerInterop/SwaClient.php
new file mode 100644
index 0000000..054fefe
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/ServerInterop/SwaClient.php
@@ -0,0 +1,53 @@
+ SOAP_1_1,
+ 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
+ 'attachment_type' => BeSimpleSoapHelper::ATTACHMENTS_TYPE_SWA,
+ 'cache_wsdl' => WSDL_CACHE_NONE,
+ 'trace' => true, // enables use of the methods SoapClient->__getLastRequest, SoapClient->__getLastRequestHeaders, SoapClient->__getLastResponse and SoapClient->__getLastResponseHeaders
+ 'classmap' => array(
+ 'downloadFile' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\downloadFile',
+ 'downloadFileResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\downloadFileResponse',
+ 'uploadFile' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\uploadFile',
+ 'uploadFileResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\uploadFileResponse',
+ ),
+ 'cli_webserver_workaround' => true, // Work around missing header access in PHP cli webserver by setting headers additionally as GET parameters.
+);
+
+$sc = new BeSimpleSoapClient(__DIR__.'/Fixtures/SwA.wsdl', $options);
+
+try {
+
+ $upload = new uploadFile();
+ $upload->name = 'upload.txt';
+ $upload->data = 'This is a test. :)';
+ $result = $sc->uploadFile($upload);
+
+ var_dump($result);
+
+ $download = new downloadFile();
+ $download->name = 'upload.txt';
+ var_dump($sc->downloadFile($download));
+} catch (Exception $e) {
+ var_dump($e);
+}
+
+// var_dump(
+// $sc->__getLastRequestHeaders(),
+// $sc->__getLastRequest(),
+// $sc->__getLastResponseHeaders(),
+// $sc->__getLastResponse()
+// );
\ No newline at end of file
diff --git a/src/BeSimple/SoapClient/Tests/ServerInterop/SwaServerInteropTest.php b/src/BeSimple/SoapClient/Tests/ServerInterop/SwaServerInteropTest.php
new file mode 100644
index 0000000..90f7fa0
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/ServerInterop/SwaServerInteropTest.php
@@ -0,0 +1,64 @@
+ SOAP_1_1,
+ 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
+ 'attachment_type' => BeSimpleSoapHelper::ATTACHMENTS_TYPE_SWA,
+ 'cache_wsdl' => WSDL_CACHE_NONE,
+ 'classmap' => array(
+ 'downloadFile' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\downloadFile',
+ 'downloadFileResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\downloadFileResponse',
+ 'uploadFile' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\uploadFile',
+ 'uploadFileResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\uploadFileResponse',
+ ),
+ 'cli_webserver_workaround' => true, // Work around missing header access in PHP cli webserver by setting headers additionally as GET parameters.
+ );
+
+ public function testUploadDownloadText()
+ {
+ $sc = new BeSimpleSoapClient(__DIR__.'/Fixtures/SwA.wsdl', $this->options);
+
+ $upload = new uploadFile();
+ $upload->name = 'upload.txt';
+ $upload->data = 'This is a test. :)';
+ $result = $sc->uploadFile($upload);
+
+ $this->assertEquals('File saved succesfully.', $result->return);
+
+ $download = new downloadFile();
+ $download->name = 'upload.txt';
+ $result = $sc->downloadFile($download);
+
+ $this->assertEquals($upload->data, $result->data);
+ }
+
+ public function testUploadDownloadImage()
+ {
+ $sc = new BeSimpleSoapClient(__DIR__.'/Fixtures/SwA.wsdl', $this->options);
+
+ $upload = new uploadFile();
+ $upload->name = 'image.jpg';
+ $upload->data = file_get_contents(__DIR__.'/Fixtures/image.jpg'); // source: http://www.freeimageslive.com/galleries/light/pics/swirl3768.jpg;
+ $result = $sc->uploadFile($upload);
+
+ $this->assertEquals('File saved succesfully.', $result->return);
+
+ $download = new downloadFile();
+ $download->name = 'image.jpg';
+ $result = $sc->downloadFile($download);
+
+ $this->assertEquals($upload->data, $result->data);
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapClient/Tests/ServerInterop/TestCase.php b/src/BeSimple/SoapClient/Tests/ServerInterop/TestCase.php
new file mode 100644
index 0000000..b0f1f40
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/ServerInterop/TestCase.php
@@ -0,0 +1,29 @@
+markTestSkipped(
+ 'The PHP cli webserver is not available with PHP 5.3.'
+ );
+ }
+
+ $ch = curl_init('http://localhost:8081/');
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
+ curl_setopt($ch, CURLOPT_HEADER, true);
+ curl_setopt($ch, CURLOPT_NOBODY, true);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+
+ if (curl_exec($ch) === false) {
+ $this->markTestSkipped(
+ 'The PHP webserver is not started on port 8081.'
+ );
+ }
+
+ curl_close($ch);
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapClient/Tests/ServerInterop/WsSecuritySigEncServer.php b/src/BeSimple/SoapClient/Tests/ServerInterop/WsSecuritySigEncServer.php
new file mode 100644
index 0000000..c8b01c6
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/ServerInterop/WsSecuritySigEncServer.php
@@ -0,0 +1,82 @@
+ SOAP_1_1,
+ 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
+ 'cache_wsdl' => WSDL_CACHE_NONE,
+ 'classmap' => array(
+ 'getBook' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBook',
+ 'getBookResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBookResponse',
+ 'getBooksByType' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBooksByType',
+ 'getBooksByTypeResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBooksByTypeResponse',
+ 'addBook' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\addBook',
+ 'addBookResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\addBookResponse',
+ 'BookInformation' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\BookInformation',
+ ),
+);
+
+class WsSecuritySigEncServer
+{
+ public function getBook(getBook $gb)
+ {
+ $bi = new BookInformation();
+ $bi->isbn = $gb->isbn;
+ $bi->title = 'title';
+ $bi->author = 'author';
+ $bi->type = 'scifi';
+
+ $br = new getBookResponse();
+ $br->getBookReturn = $bi;
+
+ return $br;
+ }
+
+ public function addBook(addBook $ab)
+ {
+ $abr = new addBookResponse();
+ $abr->addBookReturn = true;
+
+ return $abr;
+ }
+}
+
+$ss = new BeSimpleSoapServer(__DIR__.'/Fixtures/WsSecurityUserPass.wsdl', $options);
+
+$wssFilter = new BeSimpleWsSecurityFilter();
+
+// user key for signature and encryption
+$securityKeyUser = new BeSimpleWsSecurityKey();
+$securityKeyUser->addPrivateKey(XmlSecurityKey::RSA_SHA1, __DIR__.'/Fixtures/serverkey.pem', true);
+$securityKeyUser->addPublicKey(XmlSecurityKey::RSA_SHA1, __DIR__.'/Fixtures/servercert.pem', true);
+$wssFilter->setUserSecurityKeyObject($securityKeyUser);
+// service key for encryption
+$securityKeyService = new BeSimpleWsSecurityKey();
+$securityKeyService->addPrivateKey(XmlSecurityKey::TRIPLEDES_CBC);
+$securityKeyService->addPublicKey(XmlSecurityKey::RSA_1_5, __DIR__.'/Fixtures/clientcert.pem', true);
+$wssFilter->setServiceSecurityKeyObject($securityKeyService);
+// TOKEN_REFERENCE_SUBJECT_KEY_IDENTIFIER | TOKEN_REFERENCE_SECURITY_TOKEN | TOKEN_REFERENCE_THUMBPRINT_SHA1
+$wssFilter->setSecurityOptionsSignature(BeSimpleWsSecurityFilter::TOKEN_REFERENCE_SECURITY_TOKEN);
+$wssFilter->setSecurityOptionsEncryption(BeSimpleWsSecurityFilter::TOKEN_REFERENCE_THUMBPRINT_SHA1);
+
+$soapKernel = $ss->getSoapKernel();
+$soapKernel->registerFilter($wssFilter);
+
+$ss->setClass('WsSecuritySigEncServer');
+$ss->handle();
diff --git a/src/BeSimple/SoapClient/Tests/ServerInterop/WsSecuritySigEncServerClient.php b/src/BeSimple/SoapClient/Tests/ServerInterop/WsSecuritySigEncServerClient.php
new file mode 100644
index 0000000..6c7fe1d
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/ServerInterop/WsSecuritySigEncServerClient.php
@@ -0,0 +1,83 @@
+ SOAP_1_2,
+ 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
+ 'trace' => true, // enables use of the methods SoapClient->__getLastRequest, SoapClient->__getLastRequestHeaders, SoapClient->__getLastResponse and SoapClient->__getLastResponseHeaders
+ 'classmap' => array(
+ 'getBook' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBook',
+ 'getBookResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBookResponse',
+ 'getBooksByType' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBooksByType',
+ 'getBooksByTypeResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBooksByTypeResponse',
+ 'addBook' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\addBook',
+ 'addBookResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\addBookResponse',
+ 'BookInformation' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\BookInformation',
+ ),
+ 'cli_webserver_workaround' => true, // Work around missing header access in PHP cli webserver by setting headers additionally as GET parameters.
+);
+
+$sc = new BeSimpleSoapClient(__DIR__.'/Fixtures/WsSecuritySigEnc.wsdl', $options);
+
+//var_dump($sc->__getFunctions());
+//var_dump($sc->__getTypes());
+
+try {
+ $wssFilter = new BeSimpleWsSecurityFilter();
+ // user key for signature and encryption
+ $securityKeyUser = new BeSimpleWsSecurityKey();
+ $securityKeyUser->addPrivateKey(XmlSecurityKey::RSA_SHA1, __DIR__.'/Fixtures/clientkey.pem', true);
+ $securityKeyUser->addPublicKey(XmlSecurityKey::RSA_SHA1, __DIR__.'/Fixtures/clientcert.pem', true);
+ $wssFilter->setUserSecurityKeyObject($securityKeyUser);
+ // service key for encryption
+ $securityKeyService = new BeSimpleWsSecurityKey();
+ $securityKeyService->addPrivateKey(XmlSecurityKey::TRIPLEDES_CBC);
+ $securityKeyService->addPublicKey(XmlSecurityKey::RSA_1_5, __DIR__.'/Fixtures/servercert.pem', true);
+ $wssFilter->setServiceSecurityKeyObject($securityKeyService);
+ // TOKEN_REFERENCE_SUBJECT_KEY_IDENTIFIER | TOKEN_REFERENCE_SECURITY_TOKEN | TOKEN_REFERENCE_THUMBPRINT_SHA1
+ $wssFilter->setSecurityOptionsSignature(BeSimpleWsSecurityFilter::TOKEN_REFERENCE_SECURITY_TOKEN);
+ $wssFilter->setSecurityOptionsEncryption(BeSimpleWsSecurityFilter::TOKEN_REFERENCE_THUMBPRINT_SHA1);
+
+ $soapKernel = $sc->getSoapKernel();
+ $soapKernel->registerFilter($wssFilter);
+
+ $gb = new getBook();
+ $gb->isbn = '0061020052';
+ $result = $sc->getBook($gb);
+ var_dump($result->getBookReturn);
+
+ $ab = new addBook();
+ $ab->isbn = '0445203498';
+ $ab->title = 'The Dragon Never Sleeps';
+ $ab->author = 'Cook, Glen';
+ $ab->type = 'scifi';
+
+ var_dump($sc->addBook($ab));
+
+} catch (Exception $e) {
+ var_dump($e);
+}
+
+// var_dump(
+// $sc->__getLastRequestHeaders(),
+// $sc->__getLastRequest(),
+// $sc->__getLastResponseHeaders(),
+// $sc->__getLastResponse()
+// );
diff --git a/src/BeSimple/SoapClient/Tests/ServerInterop/WsSecuritySigEncServerInteropTest.php b/src/BeSimple/SoapClient/Tests/ServerInterop/WsSecuritySigEncServerInteropTest.php
new file mode 100644
index 0000000..7cbbef4
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/ServerInterop/WsSecuritySigEncServerInteropTest.php
@@ -0,0 +1,73 @@
+ SOAP_1_2,
+ 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
+ 'classmap' => array(
+ 'getBook' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBook',
+ 'getBookResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBookResponse',
+ 'getBooksByType' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBooksByType',
+ 'getBooksByTypeResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBooksByTypeResponse',
+ 'addBook' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\addBook',
+ 'addBookResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\addBookResponse',
+ 'BookInformation' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\BookInformation',
+ ),
+ 'cli_webserver_workaround' => true, // Work around missing header access in PHP cli webserver by setting headers additionally as GET parameters.
+ );
+
+ public function testSigEnc()
+ {
+ $sc = new BeSimpleSoapClient(__DIR__.'/Fixtures/WsSecuritySigEnc.wsdl', $this->options);
+
+ $wssFilter = new BeSimpleWsSecurityFilter();
+ // user key for signature and encryption
+ $securityKeyUser = new BeSimpleWsSecurityKey();
+ $securityKeyUser->addPrivateKey(XmlSecurityKey::RSA_SHA1, __DIR__.'/Fixtures/clientkey.pem', true);
+ $securityKeyUser->addPublicKey(XmlSecurityKey::RSA_SHA1, __DIR__.'/Fixtures/clientcert.pem', true);
+ $wssFilter->setUserSecurityKeyObject($securityKeyUser);
+ // service key for encryption
+ $securityKeyService = new BeSimpleWsSecurityKey();
+ $securityKeyService->addPrivateKey(XmlSecurityKey::TRIPLEDES_CBC);
+ $securityKeyService->addPublicKey(XmlSecurityKey::RSA_1_5, __DIR__.'/Fixtures/servercert.pem', true);
+ $wssFilter->setServiceSecurityKeyObject($securityKeyService);
+ // TOKEN_REFERENCE_SUBJECT_KEY_IDENTIFIER | TOKEN_REFERENCE_SECURITY_TOKEN | TOKEN_REFERENCE_THUMBPRINT_SHA1
+ $wssFilter->setSecurityOptionsSignature(BeSimpleWsSecurityFilter::TOKEN_REFERENCE_SECURITY_TOKEN);
+ $wssFilter->setSecurityOptionsEncryption(BeSimpleWsSecurityFilter::TOKEN_REFERENCE_THUMBPRINT_SHA1);
+
+ $soapKernel = $sc->getSoapKernel();
+ $soapKernel->registerFilter($wssFilter);
+
+ $gb = new getBook();
+ $gb->isbn = '0061020052';
+ $result = $sc->getBook($gb);
+ $this->assertInstanceOf('BeSimple\SoapClient\Tests\ServerInterop\Fixtures\BookInformation', $result->getBookReturn);
+
+ $ab = new addBook();
+ $ab->isbn = '0445203498';
+ $ab->title = 'The Dragon Never Sleeps';
+ $ab->author = 'Cook, Glen';
+ $ab->type = 'scifi';
+
+ $this->assertTrue((bool) $sc->addBook($ab));
+
+ // getBooksByType("scifi");
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapClient/Tests/ServerInterop/WsSecurityUserPassServer.php b/src/BeSimple/SoapClient/Tests/ServerInterop/WsSecurityUserPassServer.php
new file mode 100644
index 0000000..8a2e2dc
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/ServerInterop/WsSecurityUserPassServer.php
@@ -0,0 +1,78 @@
+ SOAP_1_1,
+ 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
+ 'cache_wsdl' => WSDL_CACHE_NONE,
+ 'classmap' => array(
+ 'getBook' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBook',
+ 'getBookResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBookResponse',
+ 'getBooksByType' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBooksByType',
+ 'getBooksByTypeResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBooksByTypeResponse',
+ 'addBook' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\addBook',
+ 'addBookResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\addBookResponse',
+ 'BookInformation' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\BookInformation',
+ ),
+);
+
+class Auth
+{
+ public static function usernamePasswordCallback($user)
+ {
+ if ($user == 'libuser') {
+ return 'books';
+ }
+
+ return null;
+ }
+}
+
+class WsSecurityUserPassServer
+{
+ public function getBook(getBook $gb)
+ {
+ $bi = new BookInformation();
+ $bi->isbn = $gb->isbn;
+ $bi->title = 'title';
+ $bi->author = 'author';
+ $bi->type = 'scifi';
+
+ $br = new getBookResponse();
+ $br->getBookReturn = $bi;
+
+ return $br;
+ }
+
+ public function addBook(addBook $ab)
+ {
+ $abr = new addBookResponse();
+ $abr->addBookReturn = true;
+
+ return $abr;
+ }
+}
+
+$ss = new BeSimpleSoapServer(__DIR__.'/Fixtures/WsSecurityUserPass.wsdl', $options);
+
+$wssFilter = new BeSimpleWsSecurityFilter();
+$wssFilter->setUsernamePasswordCallback(array('Auth', 'usernamePasswordCallback'));
+
+$soapKernel = $ss->getSoapKernel();
+$soapKernel->registerFilter($wssFilter);
+
+$ss->setClass('WsSecurityUserPassServer');
+$ss->handle();
diff --git a/src/BeSimple/SoapClient/Tests/ServerInterop/WsSecurityUserPassServerClient.php b/src/BeSimple/SoapClient/Tests/ServerInterop/WsSecurityUserPassServerClient.php
new file mode 100644
index 0000000..b69b3d9
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/ServerInterop/WsSecurityUserPassServerClient.php
@@ -0,0 +1,68 @@
+ SOAP_1_2,
+ 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
+ 'trace' => true, // enables use of the methods SoapClient->__getLastRequest, SoapClient->__getLastRequestHeaders, SoapClient->__getLastResponse and SoapClient->__getLastResponseHeaders
+ 'classmap' => array(
+ 'getBook' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBook',
+ 'getBookResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBookResponse',
+ 'getBooksByType' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBooksByType',
+ 'getBooksByTypeResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBooksByTypeResponse',
+ 'addBook' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\addBook',
+ 'addBookResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\addBookResponse',
+ 'BookInformation' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\BookInformation',
+ ),
+ 'cli_webserver_workaround' => true, // Work around missing header access in PHP cli webserver by setting headers additionally as GET parameters.
+);
+
+$sc = new BeSimpleSoapClient(__DIR__.'/Fixtures/WsSecurityUserPass.wsdl', $options);
+
+//var_dump($sc->__getFunctions());
+//var_dump($sc->__getTypes());
+
+try {
+ $wssFilter = new BeSimpleWsSecurityFilter(true, 600);
+ $wssFilter->addUserData('libuser', 'books', BeSimpleWsSecurityFilter::PASSWORD_TYPE_DIGEST);
+
+ $soapKernel = $sc->getSoapKernel();
+ $soapKernel->registerFilter($wssFilter);
+
+ $gb = new getBook();
+ $gb->isbn = '0061020052';
+ $result = $sc->getBook($gb);
+ var_dump($result->getBookReturn);
+
+ $ab = new addBook();
+ $ab->isbn = '0445203498';
+ $ab->title = 'The Dragon Never Sleeps';
+ $ab->author = 'Cook, Glen';
+ $ab->type = 'scifi';
+
+ var_dump($sc->addBook($ab));
+
+} catch (Exception $e) {
+ var_dump($e);
+}
+
+// var_dump(
+// $sc->__getLastRequestHeaders(),
+// $sc->__getLastRequest(),
+// $sc->__getLastResponseHeaders(),
+// $sc->__getLastResponse()
+// );
diff --git a/src/BeSimple/SoapClient/Tests/ServerInterop/WsSecurityUserPassServerInteropTest.php b/src/BeSimple/SoapClient/Tests/ServerInterop/WsSecurityUserPassServerInteropTest.php
new file mode 100644
index 0000000..4030507
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/ServerInterop/WsSecurityUserPassServerInteropTest.php
@@ -0,0 +1,86 @@
+ SOAP_1_2,
+ 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
+ 'classmap' => array(
+ 'getBook' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBook',
+ 'getBookResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBookResponse',
+ 'getBooksByType' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBooksByType',
+ 'getBooksByTypeResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\getBooksByTypeResponse',
+ 'addBook' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\addBook',
+ 'addBookResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\addBookResponse',
+ 'BookInformation' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\BookInformation',
+ ),
+ 'cli_webserver_workaround' => true, // Work around missing header access in PHP cli webserver by setting headers additionally as GET parameters.
+ );
+
+ public function testUserPassText()
+ {
+ $sc = new BeSimpleSoapClient(__DIR__.'/Fixtures/WsSecurityUserPass.wsdl', $this->options);
+
+ $wssFilter = new BeSimpleWsSecurityFilter(true, 600);
+ $wssFilter->addUserData('libuser', 'books', BeSimpleWsSecurityFilter::PASSWORD_TYPE_TEXT);
+
+ $soapKernel = $sc->getSoapKernel();
+ $soapKernel->registerFilter($wssFilter);
+
+ $gb = new getBook();
+ $gb->isbn = '0061020052';
+ $result = $sc->getBook($gb);
+ $this->assertInstanceOf('BeSimple\SoapClient\Tests\ServerInterop\Fixtures\BookInformation', $result->getBookReturn);
+
+ $ab = new addBook();
+ $ab->isbn = '0445203498';
+ $ab->title = 'The Dragon Never Sleeps';
+ $ab->author = 'Cook, Glen';
+ $ab->type = 'scifi';
+
+ $this->assertTrue((bool) $sc->addBook($ab));
+
+ // getBooksByType("scifi");
+ }
+
+ public function testUserPassDigest()
+ {
+ $sc = new BeSimpleSoapClient(__DIR__.'/Fixtures/WsSecurityUserPass.wsdl', $this->options);
+
+ $wssFilter = new BeSimpleWsSecurityFilter(true, 600);
+ $wssFilter->addUserData( 'libuser', 'books', BeSimpleWsSecurityFilter::PASSWORD_TYPE_DIGEST );
+
+ $soapKernel = $sc->getSoapKernel();
+ $soapKernel->registerFilter($wssFilter);
+
+ $gb = new getBook();
+ $gb->isbn = '0061020052';
+ $result = $sc->getBook($gb);
+ $this->assertInstanceOf('BeSimple\SoapClient\Tests\ServerInterop\Fixtures\BookInformation', $result->getBookReturn);
+
+ $ab = new addBook();
+ $ab->isbn = '0445203498';
+ $ab->title = 'The Dragon Never Sleeps';
+ $ab->author = 'Cook, Glen';
+ $ab->type = 'scifi';
+
+ $this->assertTrue((bool) $sc->addBook($ab));
+
+ // getBooksByType("scifi");
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapClient/Tests/bin/axis.sh b/src/BeSimple/SoapClient/Tests/bin/axis.sh
new file mode 100755
index 0000000..d143ebd
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/bin/axis.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+cd $DIR
+
+VERSION_AXIS=1.5.1
+ZIP_AXIS=axis2-$VERSION_AXIS-bin.zip
+if [[ "$VERSION_AXIS" > "1.5.1" ]]; then
+ PATH_AXIS=http://archive.apache.org/dist/axis/axis2/java/core/$VERSION_AXIS/$ZIP_AXIS
+else
+ PATH_AXIS=http://archive.apache.org/dist/ws/axis2/${VERSION_AXIS//./_}/$ZIP_AXIS
+fi
+
+if [ ! -f "$DIR/$ZIP_AXIS" ]; then
+ curl -O -s $PATH_AXIS
+fi
+
+VERSION_RAMPART=1.5
+ZIP_RAMPART=rampart-dist-$VERSION_RAMPART-bin.zip
+PATH_RAMPART=http://archive.apache.org/dist/axis/axis2/java/rampart/$VERSION_RAMPART/$ZIP_RAMPART
+
+if [ ! -f "$DIR/$ZIP_RAMPART" ]; then
+ curl -O -s $PATH_RAMPART
+fi
+
+unzip -qq "$DIR/$ZIP_AXIS"
+
+AXIS_DIR=$DIR/axis2-$VERSION_AXIS
+
+unzip -qq -j "$DIR/$ZIP_RAMPART" '*/lib/*.jar' -d $AXIS_DIR/lib
+unzip -qq -j "$DIR/$ZIP_RAMPART" '*/modules/*.mar' -d $AXIS_DIR/repository/modules
+
+cp -r $DIR/../AxisInterop/axis_services/* $AXIS_DIR/repository/services
+
+$AXIS_DIR/bin/axis2server.sh&
+
+echo "Waiting until Axis is ready on port 8080"
+while [[ -z `curl -s 'http://localhost:8080/axis2/services/' ` ]]
+do
+ echo -n "."
+ sleep 2s
+done
+
+echo "Axis is up"
\ No newline at end of file
diff --git a/src/BeSimple/SoapClient/Tests/bin/phpwebserver.sh b/src/BeSimple/SoapClient/Tests/bin/phpwebserver.sh
new file mode 100755
index 0000000..0d07b8e
--- /dev/null
+++ b/src/BeSimple/SoapClient/Tests/bin/phpwebserver.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+PHPWEBSERVEROK="$( php -r "if (version_compare(phpversion(), '5.4', '<')) { echo 'nok'; } else { echo 'ok'; }" )"
+
+if [ "$PHPWEBSERVEROK" != "ok" ]; then
+ echo "No PHP webserver available before version 5.4..."
+ exit
+fi
+
+DIR="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+cd $DIR
+
+php -S localhost:8081 -t "$DIR/.."&
+
+echo "Waiting until PHP webserver is ready on port 8081"
+while [[ -z `curl -s 'http://localhost:8081' ` ]]
+do
+ echo -n "."
+ sleep 2s
+done
+
+echo "PHP webserver is up"
\ No newline at end of file
diff --git a/src/BeSimple/SoapClient/WsSecurityFilter.php b/src/BeSimple/SoapClient/WsSecurityFilter.php
index cb3fc7c..b66aae3 100644
--- a/src/BeSimple/SoapClient/WsSecurityFilter.php
+++ b/src/BeSimple/SoapClient/WsSecurityFilter.php
@@ -15,6 +15,7 @@ namespace BeSimple\SoapClient;
use ass\XmlSecurity\DSig as XmlSecurityDSig;
use ass\XmlSecurity\Enc as XmlSecurityEnc;
use ass\XmlSecurity\Key as XmlSecurityKey;
+use ass\XmlSecurity\Pem as XmlSecurityPem;
use BeSimple\SoapCommon\FilterHelper;
use BeSimple\SoapCommon\Helper;
@@ -23,6 +24,7 @@ use BeSimple\SoapCommon\SoapRequestFilter;
use BeSimple\SoapCommon\SoapResponse as CommonSoapResponse;
use BeSimple\SoapCommon\SoapResponseFilter;
use BeSimple\SoapCommon\WsSecurityKey;
+use BeSimple\SoapCommon\WsSecurityFilterClientServer;
/**
* This plugin implements a subset of the following standards:
@@ -35,13 +37,8 @@ use BeSimple\SoapCommon\WsSecurityKey;
*
* @author Andreas Schamberger
*/
-class WsSecurityFilter implements SoapRequestFilter, SoapResponseFilter
+class WsSecurityFilter extends WsSecurityFilterClientServer implements SoapRequestFilter, SoapResponseFilter
{
- /*
- * The date format to be used with {@link \DateTime}
- */
- const DATETIME_FORMAT = 'Y-m-d\TH:i:s.000\Z';
-
/**
* (UT 3.1) Password type: plain text.
*/
@@ -52,49 +49,6 @@ class WsSecurityFilter implements SoapRequestFilter, SoapResponseFilter
*/
const PASSWORD_TYPE_DIGEST = 1;
- /**
- * (X509 3.2.1) Reference to a Subject Key Identifier
- */
- const TOKEN_REFERENCE_SUBJECT_KEY_IDENTIFIER = 0;
-
- /**
- * (X509 3.2.1) Reference to a Security Token
- */
- const TOKEN_REFERENCE_SECURITY_TOKEN = 1;
-
- /**
- * (SMS_1.1 7.3) Key Identifiers
- */
- const TOKEN_REFERENCE_THUMBPRINT_SHA1 = 2;
-
- /**
- * Actor.
- *
- * @var string
- */
- protected $actor;
-
- /**
- * (SMS 10) Add security timestamp.
- *
- * @var boolean
- */
- protected $addTimestamp;
-
- /**
- * Encrypt the signature?
- *
- * @var boolean
- */
- protected $encryptSignature;
-
- /**
- * (SMS 10) Security timestamp expires time in seconds.
- *
- * @var int
- */
- protected $expires;
-
/**
* (UT 3.1) Password.
*
@@ -109,34 +63,6 @@ class WsSecurityFilter implements SoapRequestFilter, SoapResponseFilter
*/
protected $passwordType;
- /**
- * Sign all headers.
- *
- * @var boolean
- */
- protected $signAllHeaders;
-
- /**
- * (X509 3.2) Token reference type for encryption.
- *
- * @var int
- */
- protected $tokenReferenceEncryption = null;
-
- /**
- * (X509 3.2) Token reference type for signature.
- *
- * @var int
- */
- protected $tokenReferenceSignature = null;
-
- /**
- * Service WsSecurityKey.
- *
- * @var \BeSimple\SoapCommon\WsSecurityKey
- */
- protected $serviceSecurityKey;
-
/**
* (UT 3.1) Username.
*
@@ -151,20 +77,6 @@ class WsSecurityFilter implements SoapRequestFilter, SoapResponseFilter
*/
protected $userSecurityKey;
- /**
- * Constructor.
- *
- * @param boolean $addTimestamp (SMS 10) Add security timestamp.
- * @param int $expires (SMS 10) Security timestamp expires time in seconds.
- * @param string $actor SOAP actor
- */
- public function __construct($addTimestamp = true, $expires = 300, $actor = null)
- {
- $this->addTimestamp = $addTimestamp;
- $this->expires = $expires;
- $this->actor = $actor;
- }
-
/**
* Add user data.
*
@@ -186,70 +98,10 @@ class WsSecurityFilter implements SoapRequestFilter, SoapResponseFilter
*/
public function resetFilter()
{
- $this->actor = null;
- $this->addTimestamp = null;
- $this->encryptSignature = null;
- $this->expires = null;
- $this->password = null;
- $this->passwordType = null;
- $this->serviceSecurityKey = null;
- $this->signAllHeaders = null;
- $this->tokenReferenceEncryption = null;
- $this->tokenReferenceSignature = null;
- $this->username = null;
- $this->userSecurityKey = null;
- }
-
- /**
- * Get service security key.
- *
- * @param \BeSimple\SoapCommon\WsSecurityKey $serviceSecurityKey Service security key
- *
- * @return void
- */
- public function setServiceSecurityKeyObject(WsSecurityKey $serviceSecurityKey)
- {
- $this->serviceSecurityKey = $serviceSecurityKey;
- }
-
- /**
- * Get user security key.
- *
- * @param \BeSimple\SoapCommon\WsSecurityKey $userSecurityKey User security key
- *
- * @return void
- */
- public function setUserSecurityKeyObject(WsSecurityKey $userSecurityKey)
- {
- $this->userSecurityKey = $userSecurityKey;
- }
-
- /**
- * Set security options.
- *
- * @param int $tokenReference self::TOKEN_REFERENCE_SUBJECT_KEY_IDENTIFIER | self::TOKEN_REFERENCE_SECURITY_TOKEN | self::TOKEN_REFERENCE_THUMBPRINT_SHA1
- * @param boolean $encryptSignature Encrypt signature
- *
- * @return void
- */
- public function setSecurityOptionsEncryption($tokenReference, $encryptSignature = false)
- {
- $this->tokenReferenceEncryption = $tokenReference;
- $this->encryptSignature = $encryptSignature;
- }
-
- /**
- * Set security options.
- *
- * @param int $tokenReference self::TOKEN_REFERENCE_SUBJECT_KEY_IDENTIFIER | self::TOKEN_REFERENCE_SECURITY_TOKEN | self::TOKEN_REFERENCE_THUMBPRINT_SHA1
- * @param boolean $signAllHeaders Sign all headers?
- *
- * @return void
- */
- public function setSecurityOptionsSignature($tokenReference, $signAllHeaders = false)
- {
- $this->tokenReferenceSignature = $tokenReference;
- $this->signAllHeaders = $signAllHeaders;
+ parent::resetFilter();
+ $this->password = null;
+ $this->passwordType = null;
+ $this->username = null;
}
/**
@@ -390,10 +242,8 @@ class WsSecurityFilter implements SoapRequestFilter, SoapResponseFilter
$security = $dom->getElementsByTagNameNS(Helper::NS_WSS, 'Security')->item(0);
if (null !== $security) {
// add SecurityTokenReference resolver for KeyInfo
- if (null !== $this->serviceSecurityKey) {
- $keyResolver = array($this, 'keyInfoSecurityTokenReferenceResolver');
- XmlSecurityDSig::addKeyInfoResolver(Helper::NS_WSS, 'SecurityTokenReference', $keyResolver);
- }
+ $keyResolver = array($this, 'keyInfoSecurityTokenReferenceResolver');
+ XmlSecurityDSig::addKeyInfoResolver(Helper::NS_WSS, 'SecurityTokenReference', $keyResolver);
// do we have a reference list in header
$referenceList = XmlSecurityEnc::locateReferenceList($security);
// get a list of encrypted nodes
@@ -420,162 +270,8 @@ class WsSecurityFilter implements SoapRequestFilter, SoapResponseFilter
throw new \SoapFault('wsse:FailedCheck', 'The signature or decryption was invalid');
}
}
+
+ $security->parentNode->removeChild($security);
}
}
-
- /**
- * Adds the configured KeyInfo to the parentNode.
- *
- * @param FilterHelper $filterHelper Filter helper object
- * @param int $tokenReference Token reference type
- * @param string $guid Unique ID
- * @param \ass\XmlSecurity\Key $xmlSecurityKey XML security key
- *
- * @return \DOMElement
- */
- protected function createKeyInfo(FilterHelper $filterHelper, $tokenReference, $guid, XmlSecurityKey $xmlSecurityKey = null)
- {
- $keyInfo = $filterHelper->createElement(XmlSecurityDSig::NS_XMLDSIG, 'KeyInfo');
- $securityTokenReference = $filterHelper->createElement(Helper::NS_WSS, 'SecurityTokenReference');
- $keyInfo->appendChild($securityTokenReference);
- // security token
- if (self::TOKEN_REFERENCE_SECURITY_TOKEN === $tokenReference) {
- $reference = $filterHelper->createElement(Helper::NS_WSS, 'Reference');
- $filterHelper->setAttribute($reference, null, 'URI', '#' . $guid);
- if (null !== $xmlSecurityKey) {
- $filterHelper->setAttribute($reference, null, 'ValueType', Helper::NAME_WSS_X509 . '#X509v3');
- }
- $securityTokenReference->appendChild($reference);
- // subject key identifier
- } elseif (self::TOKEN_REFERENCE_SUBJECT_KEY_IDENTIFIER === $tokenReference && null !== $xmlSecurityKey) {
- $keyIdentifier = $filterHelper->createElement(Helper::NS_WSS, 'KeyIdentifier');
- $filterHelper->setAttribute($keyIdentifier, null, 'EncodingType', Helper::NAME_WSS_SMS . '#Base64Binary');
- $filterHelper->setAttribute($keyIdentifier, null, 'ValueType', Helper::NAME_WSS_X509 . '#509SubjectKeyIdentifier');
- $securityTokenReference->appendChild($keyIdentifier);
- $certificate = $xmlSecurityKey->getX509SubjectKeyIdentifier();
- $dataNode = new \DOMText($certificate);
- $keyIdentifier->appendChild($dataNode);
- // thumbprint sha1
- } elseif (self::TOKEN_REFERENCE_THUMBPRINT_SHA1 === $tokenReference && null !== $xmlSecurityKey) {
- $keyIdentifier = $filterHelper->createElement(Helper::NS_WSS, 'KeyIdentifier');
- $filterHelper->setAttribute($keyIdentifier, null, 'EncodingType', Helper::NAME_WSS_SMS . '#Base64Binary');
- $filterHelper->setAttribute($keyIdentifier, null, 'ValueType', Helper::NAME_WSS_SMS_1_1 . '#ThumbprintSHA1');
- $securityTokenReference->appendChild($keyIdentifier);
- $thumbprintSha1 = base64_encode(sha1(base64_decode($xmlSecurityKey->getX509Certificate(true)), true));
- $dataNode = new \DOMText($thumbprintSha1);
- $keyIdentifier->appendChild($dataNode);
- }
-
- return $keyInfo;
- }
-
- /**
- * Create a list of \DOMNodes that should be encrypted.
- *
- * @param \DOMDocument $dom DOMDocument to query
- * @param \DOMElement $security Security element
- *
- * @return \DOMNodeList
- */
- protected function createNodeListForEncryption(\DOMDocument $dom, \DOMElement $security)
- {
- $xpath = new \DOMXPath($dom);
- $xpath->registerNamespace('SOAP-ENV', $dom->documentElement->namespaceURI);
- $xpath->registerNamespace('ds', XmlSecurityDSig::NS_XMLDSIG);
- if ($this->encryptSignature === true) {
- $query = '//ds:Signature | //SOAP-ENV:Body';
- } else {
- $query = '//SOAP-ENV:Body';
- }
-
- return $xpath->query($query);
- }
-
- /**
- * Create a list of \DOMNodes that should be signed.
- *
- * @param \DOMDocument $dom DOMDocument to query
- * @param \DOMElement $security Security element
- *
- * @return array(\DOMNode)
- */
- protected function createNodeListForSigning(\DOMDocument $dom, \DOMElement $security)
- {
- $nodes = array();
- $body = $dom->getElementsByTagNameNS($dom->documentElement->namespaceURI, 'Body')->item(0);
- if (null !== $body) {
- $nodes[] = $body;
- }
- foreach ($security->childNodes as $node) {
- if (XML_ELEMENT_NODE === $node->nodeType) {
- $nodes[] = $node;
- }
- }
- if ($this->signAllHeaders) {
- foreach ($security->parentNode->childNodes as $node) {
- if (XML_ELEMENT_NODE === $node->nodeType &&
- Helper::NS_WSS !== $node->namespaceURI) {
- $nodes[] = $node;
- }
- }
- }
-
- return $nodes;
- }
-
- /**
- * Gets the referenced node for the given URI.
- *
- * @param \DOMElement $node Node
- * @param string $uri URI
- *
- * @return \DOMElement
- */
- protected function getReferenceNodeForUri(\DOMElement $node, $uri)
- {
- $url = parse_url($uri);
- $referenceId = $url['fragment'];
- $query = '//*[@'.Helper::PFX_WSU.':Id="'.$referenceId.'" or @Id="'.$referenceId.'"]';
- $xpath = new \DOMXPath($node->ownerDocument);
- $xpath->registerNamespace(Helper::PFX_WSU, Helper::NS_WSU);
-
- return $xpath->query($query)->item(0);
- }
-
- /**
- * Tries to resolve a key from the given \DOMElement.
- *
- * @param \DOMElement $node Node where to resolve the key
- * @param string $algorithm XML security key algorithm
- *
- * @return \ass\XmlSecurity\Key|null
- */
- public function keyInfoSecurityTokenReferenceResolver(\DOMElement $node, $algorithm)
- {
- foreach ($node->childNodes as $key) {
- if (Helper::NS_WSS === $key->namespaceURI) {
- switch ($key->localName) {
- case 'KeyIdentifier':
-
- return $this->serviceSecurityKey->getPublicKey();
- case 'Reference':
- $uri = $key->getAttribute('URI');
- $referencedNode = $this->getReferenceNodeForUri($node, $uri);
-
- if (XmlSecurityEnc::NS_XMLENC === $referencedNode->namespaceURI
- && 'EncryptedKey' == $referencedNode->localName) {
- $key = XmlSecurityEnc::decryptEncryptedKey($referencedNode, $this->userSecurityKey->getPrivateKey());
-
- return XmlSecurityKey::factory($algorithm, $key, XmlSecurityKey::TYPE_PRIVATE);
- } else {
- //$valueType = $key->getAttribute('ValueType');
-
- return $this->serviceSecurityKey->getPublicKey();
- }
- }
- }
- }
-
- return null;
- }
}
\ No newline at end of file
diff --git a/src/BeSimple/SoapClient/WsdlDownloader.php b/src/BeSimple/SoapClient/WsdlDownloader.php
index 6e403ce..97a7d67 100644
--- a/src/BeSimple/SoapClient/WsdlDownloader.php
+++ b/src/BeSimple/SoapClient/WsdlDownloader.php
@@ -74,11 +74,8 @@ class WsdlDownloader
// get current WSDL caching config
$this->cacheEnabled = $cacheWsdl === Cache::TYPE_NONE ? Cache::DISABLED : Cache::ENABLED == Cache::isEnabled();
-
- if ($this->cacheEnabled) {
- $this->cacheDir = Cache::getDirectory();
- $this->cacheTtl = Cache::getLifetime();
- }
+ $this->cacheDir = Cache::getDirectory();
+ $this->cacheTtl = Cache::getLifetime();
}
/**
diff --git a/src/BeSimple/SoapCommon/Converter/SwaTypeConverter.php b/src/BeSimple/SoapCommon/Converter/SwaTypeConverter.php
index 40d6372..138b973 100644
--- a/src/BeSimple/SoapCommon/Converter/SwaTypeConverter.php
+++ b/src/BeSimple/SoapCommon/Converter/SwaTypeConverter.php
@@ -83,7 +83,7 @@ class SwaTypeConverter implements TypeConverterInterface, SoapKernelAwareInterfa
$this->soapKernel->addAttachment($part);
- return sprintf('<%s href="%s"/>', $this->getTypeName(), $contentId);
+ return sprintf('<%s href="%s"/>', $this->getTypeName(), 'cid:' . $contentId);
}
/**
diff --git a/src/BeSimple/SoapCommon/WsSecurityFilterClientServer.php b/src/BeSimple/SoapCommon/WsSecurityFilterClientServer.php
new file mode 100644
index 0000000..00231cc
--- /dev/null
+++ b/src/BeSimple/SoapCommon/WsSecurityFilterClientServer.php
@@ -0,0 +1,358 @@
+
+ * (c) Francis Besset
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace BeSimple\SoapCommon;
+
+use ass\XmlSecurity\DSig as XmlSecurityDSig;
+use ass\XmlSecurity\Enc as XmlSecurityEnc;
+use ass\XmlSecurity\Key as XmlSecurityKey;
+use ass\XmlSecurity\Pem as XmlSecurityPem;
+
+use BeSimple\SoapCommon\FilterHelper;
+use BeSimple\SoapCommon\Helper;
+use BeSimple\SoapCommon\SoapRequest as CommonSoapRequest;
+use BeSimple\SoapCommon\SoapRequestFilter;
+use BeSimple\SoapCommon\SoapResponse as CommonSoapResponse;
+use BeSimple\SoapCommon\SoapResponseFilter;
+use BeSimple\SoapCommon\WsSecurityKey;
+
+/**
+ * WS-Security common code for client & server.
+ *
+ * @author Andreas Schamberger
+ */
+abstract class WsSecurityFilterClientServer
+{
+ /**
+ * The date format to be used with {@link \DateTime}
+ */
+ const DATETIME_FORMAT = 'Y-m-d\TH:i:s.000\Z';
+
+ /**
+ * (X509 3.2.1) Reference to a Subject Key Identifier
+ */
+ const TOKEN_REFERENCE_SUBJECT_KEY_IDENTIFIER = 0;
+
+ /**
+ * (X509 3.2.1) Reference to a Security Token
+ */
+ const TOKEN_REFERENCE_SECURITY_TOKEN = 1;
+
+ /**
+ * (SMS_1.1 7.3) Key Identifiers
+ */
+ const TOKEN_REFERENCE_THUMBPRINT_SHA1 = 2;
+
+ /**
+ * Actor.
+ *
+ * @var string
+ */
+ protected $actor;
+
+ /**
+ * (SMS 10) Add security timestamp.
+ *
+ * @var boolean
+ */
+ protected $addTimestamp;
+
+ /**
+ * Encrypt the signature?
+ *
+ * @var boolean
+ */
+ protected $encryptSignature;
+
+ /**
+ * (SMS 10) Security timestamp expires time in seconds.
+ *
+ * @var int
+ */
+ protected $expires;
+
+ /**
+ * Sign all headers.
+ *
+ * @var boolean
+ */
+ protected $signAllHeaders;
+
+ /**
+ * (X509 3.2) Token reference type for encryption.
+ *
+ * @var int
+ */
+ protected $tokenReferenceEncryption = null;
+
+ /**
+ * (X509 3.2) Token reference type for signature.
+ *
+ * @var int
+ */
+ protected $tokenReferenceSignature = null;
+
+ /**
+ * Service WsSecurityKey.
+ *
+ * @var \BeSimple\SoapCommon\WsSecurityKey
+ */
+ protected $serviceSecurityKey;
+
+ /**
+ * User WsSecurityKey.
+ *
+ * @var \BeSimple\SoapCommon\WsSecurityKey
+ */
+ protected $userSecurityKey;
+
+ /**
+ * Constructor.
+ *
+ * @param boolean $addTimestamp (SMS 10) Add security timestamp.
+ * @param int $expires (SMS 10) Security timestamp expires time in seconds.
+ * @param string $actor SOAP actor
+ */
+ public function __construct($addTimestamp = true, $expires = 300, $actor = null)
+ {
+ $this->addTimestamp = $addTimestamp;
+ $this->expires = $expires;
+ $this->actor = $actor;
+ }
+
+ /**
+ * Reset all properties to default values.
+ */
+ public function resetFilter()
+ {
+ $this->actor = null;
+ $this->addTimestamp = null;
+ $this->encryptSignature = null;
+ $this->expires = null;
+ $this->serviceSecurityKey = null;
+ $this->signAllHeaders = null;
+ $this->tokenReferenceEncryption = null;
+ $this->tokenReferenceSignature = null;
+ $this->userSecurityKey = null;
+ }
+
+ /**
+ * Set service security key.
+ *
+ * @param \BeSimple\SoapCommon\WsSecurityKey $serviceSecurityKey Service security key
+ *
+ * @return void
+ */
+ public function setServiceSecurityKeyObject(WsSecurityKey $serviceSecurityKey)
+ {
+ $this->serviceSecurityKey = $serviceSecurityKey;
+ }
+
+ /**
+ * Set user security key.
+ *
+ * @param \BeSimple\SoapCommon\WsSecurityKey $userSecurityKey User security key
+ *
+ * @return void
+ */
+ public function setUserSecurityKeyObject(WsSecurityKey $userSecurityKey)
+ {
+ $this->userSecurityKey = $userSecurityKey;
+ }
+
+ /**
+ * Set security options.
+ *
+ * @param int $tokenReference self::TOKEN_REFERENCE_SUBJECT_KEY_IDENTIFIER | self::TOKEN_REFERENCE_SECURITY_TOKEN | self::TOKEN_REFERENCE_THUMBPRINT_SHA1
+ * @param boolean $encryptSignature Encrypt signature
+ *
+ * @return void
+ */
+ public function setSecurityOptionsEncryption($tokenReference, $encryptSignature = false)
+ {
+ $this->tokenReferenceEncryption = $tokenReference;
+ $this->encryptSignature = $encryptSignature;
+ }
+
+ /**
+ * Set security options.
+ *
+ * @param int $tokenReference self::TOKEN_REFERENCE_SUBJECT_KEY_IDENTIFIER | self::TOKEN_REFERENCE_SECURITY_TOKEN | self::TOKEN_REFERENCE_THUMBPRINT_SHA1
+ * @param boolean $signAllHeaders Sign all headers?
+ *
+ * @return void
+ */
+ public function setSecurityOptionsSignature($tokenReference, $signAllHeaders = false)
+ {
+ $this->tokenReferenceSignature = $tokenReference;
+ $this->signAllHeaders = $signAllHeaders;
+ }
+
+ /**
+ * Adds the configured KeyInfo to the parentNode.
+ *
+ * @param FilterHelper $filterHelper Filter helper object
+ * @param int $tokenReference Token reference type
+ * @param string $guid Unique ID
+ * @param \ass\XmlSecurity\Key $xmlSecurityKey XML security key
+ *
+ * @return \DOMElement
+ */
+ protected function createKeyInfo(FilterHelper $filterHelper, $tokenReference, $guid, XmlSecurityKey $xmlSecurityKey = null)
+ {
+ $keyInfo = $filterHelper->createElement(XmlSecurityDSig::NS_XMLDSIG, 'KeyInfo');
+ $securityTokenReference = $filterHelper->createElement(Helper::NS_WSS, 'SecurityTokenReference');
+ $keyInfo->appendChild($securityTokenReference);
+ // security token
+ if (self::TOKEN_REFERENCE_SECURITY_TOKEN === $tokenReference) {
+ $reference = $filterHelper->createElement(Helper::NS_WSS, 'Reference');
+ $filterHelper->setAttribute($reference, null, 'URI', '#' . $guid);
+ if (null !== $xmlSecurityKey) {
+ $filterHelper->setAttribute($reference, null, 'ValueType', Helper::NAME_WSS_X509 . '#X509v3');
+ }
+ $securityTokenReference->appendChild($reference);
+ // subject key identifier
+ } elseif (self::TOKEN_REFERENCE_SUBJECT_KEY_IDENTIFIER === $tokenReference && null !== $xmlSecurityKey) {
+ $keyIdentifier = $filterHelper->createElement(Helper::NS_WSS, 'KeyIdentifier');
+ $filterHelper->setAttribute($keyIdentifier, null, 'EncodingType', Helper::NAME_WSS_SMS . '#Base64Binary');
+ $filterHelper->setAttribute($keyIdentifier, null, 'ValueType', Helper::NAME_WSS_X509 . '#509SubjectKeyIdentifier');
+ $securityTokenReference->appendChild($keyIdentifier);
+ $certificate = $xmlSecurityKey->getX509SubjectKeyIdentifier();
+ $dataNode = new \DOMText($certificate);
+ $keyIdentifier->appendChild($dataNode);
+ // thumbprint sha1
+ } elseif (self::TOKEN_REFERENCE_THUMBPRINT_SHA1 === $tokenReference && null !== $xmlSecurityKey) {
+ $keyIdentifier = $filterHelper->createElement(Helper::NS_WSS, 'KeyIdentifier');
+ $filterHelper->setAttribute($keyIdentifier, null, 'EncodingType', Helper::NAME_WSS_SMS . '#Base64Binary');
+ $filterHelper->setAttribute($keyIdentifier, null, 'ValueType', Helper::NAME_WSS_SMS_1_1 . '#ThumbprintSHA1');
+ $securityTokenReference->appendChild($keyIdentifier);
+ $thumbprintSha1 = base64_encode(sha1(base64_decode($xmlSecurityKey->getX509Certificate(true)), true));
+ $dataNode = new \DOMText($thumbprintSha1);
+ $keyIdentifier->appendChild($dataNode);
+ }
+
+ return $keyInfo;
+ }
+
+ /**
+ * Create a list of \DOMNodes that should be encrypted.
+ *
+ * @param \DOMDocument $dom DOMDocument to query
+ * @param \DOMElement $security Security element
+ *
+ * @return \DOMNodeList
+ */
+ protected function createNodeListForEncryption(\DOMDocument $dom, \DOMElement $security)
+ {
+ $xpath = new \DOMXPath($dom);
+ $xpath->registerNamespace('SOAP-ENV', $dom->documentElement->namespaceURI);
+ $xpath->registerNamespace('ds', XmlSecurityDSig::NS_XMLDSIG);
+ if ($this->encryptSignature === true) {
+ $query = '//ds:Signature | //SOAP-ENV:Body';
+ } else {
+ $query = '//SOAP-ENV:Body';
+ }
+
+ return $xpath->query($query);
+ }
+
+ /**
+ * Create a list of \DOMNodes that should be signed.
+ *
+ * @param \DOMDocument $dom DOMDocument to query
+ * @param \DOMElement $security Security element
+ *
+ * @return array(\DOMNode)
+ */
+ protected function createNodeListForSigning(\DOMDocument $dom, \DOMElement $security)
+ {
+ $nodes = array();
+ $body = $dom->getElementsByTagNameNS($dom->documentElement->namespaceURI, 'Body')->item(0);
+ if (null !== $body) {
+ $nodes[] = $body;
+ }
+ foreach ($security->childNodes as $node) {
+ if (XML_ELEMENT_NODE === $node->nodeType) {
+ $nodes[] = $node;
+ }
+ }
+ if ($this->signAllHeaders) {
+ foreach ($security->parentNode->childNodes as $node) {
+ if (XML_ELEMENT_NODE === $node->nodeType &&
+ Helper::NS_WSS !== $node->namespaceURI) {
+ $nodes[] = $node;
+ }
+ }
+ }
+
+ return $nodes;
+ }
+
+ /**
+ * Gets the referenced node for the given URI.
+ *
+ * @param \DOMElement $node Node
+ * @param string $uri URI
+ *
+ * @return \DOMElement
+ */
+ protected function getReferenceNodeForUri(\DOMElement $node, $uri)
+ {
+ $url = parse_url($uri);
+ $referenceId = $url['fragment'];
+ $query = '//*[@'.Helper::PFX_WSU.':Id="'.$referenceId.'" or @Id="'.$referenceId.'"]';
+ $xpath = new \DOMXPath($node->ownerDocument);
+ $xpath->registerNamespace(Helper::PFX_WSU, Helper::NS_WSU);
+
+ return $xpath->query($query)->item(0);
+ }
+
+
+ /**
+ * Tries to resolve a key from the given \DOMElement.
+ *
+ * @param \DOMElement $node Node where to resolve the key
+ * @param string $algorithm XML security key algorithm
+ *
+ * @return \ass\XmlSecurity\Key|null
+ */
+ public function keyInfoSecurityTokenReferenceResolver(\DOMElement $node, $algorithm)
+ {
+ foreach ($node->childNodes as $key) {
+ if (Helper::NS_WSS === $key->namespaceURI) {
+ switch ($key->localName) {
+ case 'KeyIdentifier':
+
+ return $this->serviceSecurityKey->getPublicKey();
+ case 'Reference':
+ $uri = $key->getAttribute('URI');
+ $referencedNode = $this->getReferenceNodeForUri($node, $uri);
+
+ if (XmlSecurityEnc::NS_XMLENC === $referencedNode->namespaceURI
+ && 'EncryptedKey' == $referencedNode->localName) {
+ $key = XmlSecurityEnc::decryptEncryptedKey($referencedNode, $this->userSecurityKey->getPrivateKey());
+
+ return XmlSecurityKey::factory($algorithm, $key, false, XmlSecurityKey::TYPE_PRIVATE);
+ } elseif (Helper::NS_WSS === $referencedNode->namespaceURI
+ && 'BinarySecurityToken' == $referencedNode->localName) {
+
+ $key = XmlSecurityPem::formatKeyInPemFormat($referencedNode->textContent);
+
+ return XmlSecurityKey::factory(XmlSecurityKey::RSA_SHA1, $key, false, XmlSecurityKey::TYPE_PUBLIC);
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapServer/SoapRequest.php b/src/BeSimple/SoapServer/SoapRequest.php
index 0964771..4f6e53c 100644
--- a/src/BeSimple/SoapServer/SoapRequest.php
+++ b/src/BeSimple/SoapServer/SoapRequest.php
@@ -32,10 +32,21 @@ class SoapRequest extends CommonSoapRequest
*/
public static function create($content, $version)
{
- $content = is_null($content) ? file_get_contents("php://input") : $content;
$location = self::getCurrentUrl();
- $action = isset($_SERVER[SoapMessage::SOAP_ACTION_HEADER]) ? $_SERVER[SoapMessage::SOAP_ACTION_HEADER] : null;
- $contentType = $_SERVER[SoapMessage::CONTENT_TYPE_HEADER];
+ /*
+ * Work around missing header/php://input access in PHP cli webserver by
+ * setting headers additionally as GET parameters and SOAP request body
+ * explicitly as POST variable
+ */
+ if (php_sapi_name() == "cli-server") {
+ $content = is_null($content) ? $_POST['request'] : $content;
+ $action = $_GET[SoapMessage::SOAP_ACTION_HEADER];
+ $contentType = $_GET[SoapMessage::CONTENT_TYPE_HEADER];
+ } else {
+ $content = is_null($content) ? file_get_contents("php://input") : $content;
+ $action = isset($_SERVER[SoapMessage::SOAP_ACTION_HEADER]) ? $_SERVER[SoapMessage::SOAP_ACTION_HEADER] : null];
+ $contentType = $_SERVER[SoapMessage::CONTENT_TYPE_HEADER];
+ }
$request = new SoapRequest();
// $content is if unmodified from SoapClient not a php string type!
diff --git a/src/BeSimple/SoapServer/SoapServer.php b/src/BeSimple/SoapServer/SoapServer.php
index 045dcd6..9667df6 100644
--- a/src/BeSimple/SoapServer/SoapServer.php
+++ b/src/BeSimple/SoapServer/SoapServer.php
@@ -70,7 +70,12 @@ class SoapServer extends \SoapServer
$soapRequest = SoapRequest::create($request, $this->soapVersion);
// handle actual SOAP request
- $soapResponse = $this->handle2($soapRequest);
+ try {
+ $soapResponse = $this->handle2($soapRequest);
+ } catch (\SoapFault $fault) {
+ // issue an error to the client
+ $this->fault($fault->faultcode, $fault->faultstring);
+ }
// send SOAP response to client
$soapResponse->send();
diff --git a/src/BeSimple/SoapServer/WsSecurityFilter.php b/src/BeSimple/SoapServer/WsSecurityFilter.php
new file mode 100644
index 0000000..6e412b2
--- /dev/null
+++ b/src/BeSimple/SoapServer/WsSecurityFilter.php
@@ -0,0 +1,244 @@
+
+ * (c) Francis Besset
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace BeSimple\SoapServer;
+
+use ass\XmlSecurity\DSig as XmlSecurityDSig;
+use ass\XmlSecurity\Enc as XmlSecurityEnc;
+use ass\XmlSecurity\Key as XmlSecurityKey;
+use ass\XmlSecurity\Pem as XmlSecurityPem;
+
+use BeSimple\SoapCommon\FilterHelper;
+use BeSimple\SoapCommon\Helper;
+use BeSimple\SoapCommon\SoapRequest as CommonSoapRequest;
+use BeSimple\SoapCommon\SoapRequestFilter;
+use BeSimple\SoapCommon\SoapResponse as CommonSoapResponse;
+use BeSimple\SoapCommon\SoapResponseFilter;
+use BeSimple\SoapCommon\WsSecurityKey;
+use BeSimple\SoapCommon\WsSecurityFilterClientServer;
+
+/**
+ * This plugin implements a subset of the following standards:
+ * * Web Services Security: SOAP Message Security 1.0 (WS-Security 2004)
+ * http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0.pdf
+ * * Web Services Security UsernameToken Profile 1.0
+ * http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdf
+ * * Web Services Security X.509 Certificate Token Profile
+ * http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0.pdf
+ *
+ * @author Andreas Schamberger
+ */
+class WsSecurityFilter extends WsSecurityFilterClientServer implements SoapRequestFilter, SoapResponseFilter
+{
+ /**
+ * Username/password callback that returns password or null.
+ *
+ * @var callable
+ */
+ protected $usernamePasswordCallback;
+
+ /**
+ * Set username/password callback that returns password or null.
+ *
+ * @param callable $callback Username/password callback function
+ *
+ * @return void
+ */
+ public function setUsernamePasswordCallback($callback)
+ {
+ $this->usernamePasswordCallback = $callback;
+ }
+
+ /**
+ * Reset all properties to default values.
+ */
+ public function resetFilter()
+ {
+ parent::resetFilter();
+ $this->usernamePasswordCallback = null;
+ }
+
+ /**
+ * Modify the given request XML.
+ *
+ * @param \BeSimple\SoapCommon\SoapRequest $request SOAP request
+ *
+ * @return void
+ */
+ public function filterRequest(CommonSoapRequest $request)
+ {
+ // get \DOMDocument from SOAP request
+ $dom = $request->getContentDocument();
+
+ // locate security header
+ $security = $dom->getElementsByTagNameNS(Helper::NS_WSS, 'Security')->item(0);
+ if (null !== $security) {
+
+ // is security header still valid?
+ $query = '//'.Helper::PFX_WSU.':Timestamp/'.Helper::PFX_WSU.':Expires';
+ $xpath = new \DOMXPath($dom);
+ $xpath->registerNamespace(Helper::PFX_WSU, Helper::NS_WSU);
+ $expires = $xpath->query($query, $security)->item(0);
+
+ if (null !== $expires) {
+ $expiresDatetime = \DateTime::createFromFormat(self::DATETIME_FORMAT, $expires->textContent, new \DateTimeZone('UTC'));
+ $currentDatetime = new \DateTime('now', new \DateTimeZone('UTC'));
+
+ if ($currentDatetime > $expiresDatetime) {
+ throw new \SoapFault('wsu:MessageExpired', 'Security semantics are expired');
+ }
+ }
+
+ $usernameToken = $security->getElementsByTagNameNS(Helper::NS_WSS, 'UsernameToken')->item(0);
+ if (null !== $usernameToken) {
+ $usernameTokenUsername = $usernameToken->getElementsByTagNameNS(Helper::NS_WSS, 'Username')->item(0);
+ $usernameTokenPassword = $usernameToken->getElementsByTagNameNS(Helper::NS_WSS, 'Password')->item(0);
+
+ $password = call_user_func($this->usernamePasswordCallback, $usernameTokenUsername->textContent);
+
+ if ($usernameTokenPassword->getAttribute('Type') == Helper::NAME_WSS_UTP . '#PasswordDigest') {
+ $nonce = $usernameToken->getElementsByTagNameNS(Helper::NS_WSS, 'Nonce')->item(0);
+ $created = $usernameToken->getElementsByTagNameNS(Helper::NS_WSU, 'Created')->item(0);
+ $password = base64_encode(sha1(base64_decode($nonce->textContent) . $created->textContent . $password, true));
+ }
+
+ if (null === $password || $usernameTokenPassword->textContent != $password) {
+ throw new \SoapFault('wsse:FailedAuthentication', 'The security token could not be authenticated or authorized');
+ }
+ }
+
+ // add SecurityTokenReference resolver for KeyInfo
+ $keyResolver = array($this, 'keyInfoSecurityTokenReferenceResolver');
+ XmlSecurityDSig::addKeyInfoResolver(Helper::NS_WSS, 'SecurityTokenReference', $keyResolver);
+
+ // do we have a reference list in header
+ $referenceList = XmlSecurityEnc::locateReferenceList($security);
+ // get a list of encrypted nodes
+ $encryptedNodes = XmlSecurityEnc::locateEncryptedData($dom, $referenceList);
+ // decrypt them
+ if (null !== $encryptedNodes) {
+ foreach ($encryptedNodes as $encryptedNode) {
+ XmlSecurityEnc::decryptNode($encryptedNode);
+ }
+ }
+
+ // locate signature node
+ $signature = XmlSecurityDSig::locateSignature($security);
+ if (null !== $signature) {
+ // verify references
+ $options = array(
+ 'id_ns_prefix' => Helper::PFX_WSU,
+ 'id_prefix_ns' => Helper::NS_WSU,
+ );
+ if (XmlSecurityDSig::verifyReferences($signature, $options) !== true) {
+ throw new \SoapFault('wsse:FailedCheck', 'The signature or decryption was invalid');
+ }
+ // verify signature
+ if (XmlSecurityDSig::verifyDocumentSignature($signature) !== true) {
+ throw new \SoapFault('wsse:FailedCheck', 'The signature or decryption was invalid');
+ }
+ }
+
+ $security->parentNode->removeChild($security);
+ }
+ }
+
+ /**
+ * Modify the given request XML.
+ *
+ * @param \BeSimple\SoapCommon\SoapResponse $response SOAP response
+ *
+ * @return void
+ */
+ public function filterResponse(CommonSoapResponse $response)
+ {
+ // get \DOMDocument from SOAP response
+ $dom = $response->getContentDocument();
+
+ // create FilterHelper
+ $filterHelper = new FilterHelper($dom);
+
+ // add the neccessary namespaces
+ $filterHelper->addNamespace(Helper::PFX_WSS, Helper::NS_WSS);
+ $filterHelper->addNamespace(Helper::PFX_WSU, Helper::NS_WSU);
+ $filterHelper->registerNamespace(XmlSecurityDSig::PFX_XMLDSIG, XmlSecurityDSig::NS_XMLDSIG);
+
+ // init timestamp
+ $dt = new \DateTime('now', new \DateTimeZone('UTC'));
+ $createdTimestamp = $dt->format(self::DATETIME_FORMAT);
+
+ // create security header
+ $security = $filterHelper->createElement(Helper::NS_WSS, 'Security');
+ $filterHelper->addHeaderElement($security, true, $this->actor, $response->getVersion());
+
+ if (true === $this->addTimestamp || null !== $this->expires) {
+ $timestamp = $filterHelper->createElement(Helper::NS_WSU, 'Timestamp');
+ $created = $filterHelper->createElement(Helper::NS_WSU, 'Created', $createdTimestamp);
+ $timestamp->appendChild($created);
+ if (null !== $this->expires) {
+ $dt->modify('+' . $this->expires . ' seconds');
+ $expiresTimestamp = $dt->format(self::DATETIME_FORMAT);
+ $expires = $filterHelper->createElement(Helper::NS_WSU, 'Expires', $expiresTimestamp);
+ $timestamp->appendChild($expires);
+ }
+ $security->appendChild($timestamp);
+ }
+
+ if (null !== $this->userSecurityKey && $this->userSecurityKey->hasKeys()) {
+ $guid = 'CertId-' . Helper::generateUUID();
+ // add token references
+ $keyInfo = null;
+ if (null !== $this->tokenReferenceSignature) {
+ $keyInfo = $this->createKeyInfo($filterHelper, $this->tokenReferenceSignature, $guid, $this->userSecurityKey->getPublicKey());
+ }
+ $nodes = $this->createNodeListForSigning($dom, $security);
+ $signature = XmlSecurityDSig::createSignature($this->userSecurityKey->getPrivateKey(), XmlSecurityDSig::EXC_C14N, $security, null, $keyInfo);
+ $options = array(
+ 'id_ns_prefix' => Helper::PFX_WSU,
+ 'id_prefix_ns' => Helper::NS_WSU,
+ );
+ foreach ($nodes as $node) {
+ XmlSecurityDSig::addNodeToSignature($signature, $node, XmlSecurityDSig::SHA1, XmlSecurityDSig::EXC_C14N, $options);
+ }
+ XmlSecurityDSig::signDocument($signature, $this->userSecurityKey->getPrivateKey(), XmlSecurityDSig::EXC_C14N);
+
+ $publicCertificate = $this->userSecurityKey->getPublicKey()->getX509Certificate(true);
+ $binarySecurityToken = $filterHelper->createElement(Helper::NS_WSS, 'BinarySecurityToken', $publicCertificate);
+ $filterHelper->setAttribute($binarySecurityToken, null, 'EncodingType', Helper::NAME_WSS_SMS . '#Base64Binary');
+ $filterHelper->setAttribute($binarySecurityToken, null, 'ValueType', Helper::NAME_WSS_X509 . '#X509v3');
+ $filterHelper->setAttribute($binarySecurityToken, Helper::NS_WSU, 'Id', $guid);
+ $security->insertBefore($binarySecurityToken, $signature);
+
+ // encrypt soap document
+ if (null !== $this->serviceSecurityKey && $this->serviceSecurityKey->hasKeys()) {
+ $guid = 'EncKey-' . Helper::generateUUID();
+ // add token references
+ $keyInfo = null;
+ if (null !== $this->tokenReferenceEncryption) {
+ $keyInfo = $this->createKeyInfo($filterHelper, $this->tokenReferenceEncryption, $guid, $this->serviceSecurityKey->getPublicKey());
+ }
+ $encryptedKey = XmlSecurityEnc::createEncryptedKey($guid, $this->serviceSecurityKey->getPrivateKey(), $this->serviceSecurityKey->getPublicKey(), $security, $signature, $keyInfo);
+ $referenceList = XmlSecurityEnc::createReferenceList($encryptedKey);
+ // token reference to encrypted key
+ $keyInfo = $this->createKeyInfo($filterHelper, self::TOKEN_REFERENCE_SECURITY_TOKEN, $guid);
+ $nodes = $this->createNodeListForEncryption($dom, $security);
+ foreach ($nodes as $node) {
+ $type = XmlSecurityEnc::ELEMENT;
+ if ($node->localName == 'Body') {
+ $type = XmlSecurityEnc::CONTENT;
+ }
+ XmlSecurityEnc::encryptNode($node, $type, $this->serviceSecurityKey->getPrivateKey(), $referenceList, $keyInfo);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file