Signature Verification on the WS * Server

I want to verify the signature for a soap request on a soap server implemented in php.

Server Code:

$Server = new SoapServer(); $d = new DOMDocument(); $d->load('php://input'); $s = new WSSESoapServer($d); try { if($s->process()) { // Valid signature $Server->handle($s->saveXML()); } else { throw new Exception('Invalid signature'); } } catch (Exception $e) { echo "server exception: " . $e; } 

Error:

 exception 'Exception' with message 'Error loading key to handle Signature' in /<path>/wse/src/WSSESoapServer.php:146 

I have implemented a client for signing SOAP requests using this library: https://github.com/robrichards/wse-php . There are no examples of how to implement a server ...

How to download a public key to verify a signature?

[Edit] Now I was able to download the attached key using

  $key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'public')); $key->loadKey(CERT, true); 

I do not receive an error when verifying a signature:

 $x = new XMLSecurityDSig(); $d = $x->locateSignature($soapDoc); $valid = $x->verify($key); 

However, the value of $ valid is always false. I have no idea whether this is due to the key being loaded incorrectly or actually invalid. I can find very little information about implementing a SOAP server with PHP and no information about implementing a SOAP server that relies on verifying a signed request.

EXPLANATION

  • My client is talking to a remote web service and receiving a confirmation.

  • Then the remote server takes some time to process my request.

  • The remote client (which I do not control) then makes a request to my service.

The last step is where I am having trouble verifying the signature

+6
source share
1 answer

Well, anyway, your first approach looks good to me, my server has the same structure. Unfortunately, WSSESoapServer does not inherit from SoapServer, therefore not really SoapServer, but rather SoapSignatureValidator and should be called like . It would be easy to fix this behavior so that you do not need a separate instance of SoapServer (it should be transparent and automatic).

 <?php require 'soap-server-wsse.php'; try { // get soap message $xmlSoap = DOMDocument::load('php://input'); // validate signature $validateSignature = new WSSESoapServer($xmlSoap); if(!$validateSignature->process()) file_put_contents("log.txt", "soapserver: SIGNATURE VALIDATION ERROR - CONTINUING WITHOUT SIGNATURE\n", FILE_APPEND); //throw new Exception('Invalid Signature'); # this would cancel the execution and not send an answer $sServer = new SoapServer($wsdl); // actually process the soap message and create & send answer //$sServer->setClass() or setObject() or set setFunction() $sServer->handle($validateSignature->saveXML()); } catch (Exception $fault) { file_put_contents("log.txt", "soapserver soapfault: ".print_r($fault, true), FILE_APPEND); } ?> 
0
source

All Articles