Я хочу проверить подпись для запроса мыла на мыльном сервере, реализованном в php.
Код сервера:
$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;
}
Ошибка:
exception 'Exception' with message 'Error loading key to handle Signature' in /<path>/wse/src/WSSESoapServer.php:146
Я реализовал клиент для подписи запросов SOAP с использованием этой библиотеки: https://github.com/robrichards/wse-php. Там нет примеров того, как реализовать сервер …
Как загрузить открытый ключ для проверки подписи?
[Редактировать] Теперь я могу загрузить прилагаемый ключ, используя $key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'public'));
$key->loadKey(CERT, true);
Я больше не получаю сообщение об ошибке при проверке подписи:
$x = new XMLSecurityDSig();
$d = $x->locateSignature($soapDoc);
$valid = $x->verify($key);
Тем не менее, $ valid всегда false. Я понятия не имею, если это потому, что ключ загружен неправильно или на самом деле является недействительным. Я могу найти очень мало информации о реализации SOAP-сервера с PHP и никакой информации о реализации SOAP-сервера, который опирается на проверку подписанного запроса.
ПОЯСНЕНИЯ
Мой клиент общается с удаленным веб-сервисом и получает подтверждение.
Затем удаленному серверу требуется некоторое время для обработки моего запроса.
Удаленный клиент (который я не могу контролировать) затем делает запрос
мой сервис.
Последний шаг, где у меня проблемы с проверкой подписи
Ну, в любом случае, ваш первый подход выглядит хорошо для меня, мой сервер имеет такую же структуру. К несчастью, WSSESoapServer
не наследуется от SoapServer, при этом есть не действительно SoapServer, а скорее SoapSignatureValidator и должен называться так. Было бы легко исправить это поведение, чтобы не нуждаться в отдельном SoapServer
экземпляр (должен быть прозрачным и автоматически).
<?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);
}
?>
Других решений пока нет …