Проверка на подпис в изпълнението на WS* сървър

Искам да проверя подпис за заявка за сапун на сървър за сапун, внедрен в 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 винаги е невярно. Нямам представа дали е защото ключът е зареден грешно или всъщност е невалиден. Мога да намеря много малко информация за внедряване на SOAP сървър с PHP и никаква информация за внедряване на SOAP сървър, който разчита на проверка на подписана заявка.

ПОЯСНЕНИЕ

  1. Клиентът ми говори с отдалечена уеб услуга и получава потвърждение.

  2. След това отдалеченият сървър отнема известно време, за да обработи заявката ми.

  3. След това отдалечен клиент (над който нямам контрол) отправя заявка към моята услуга.

Последната стъпка е мястото, където имам проблеми с проверката на подписа


person soulfreshner    schedule 22.10.2015    source източник
comment
Струва ми се, че WSSESoapServer автоматично открива и валидира подписи в сапунено съобщение. Така че първият ви подход трябва да е ок, не трябва да зареждате ръчно ключ или да проверявате. Но: WSSESoapServer изисква подписаното сапунено съобщение да включва подписа И публичния ключ за проверка на подписа.   -  person smat88dd    schedule 02.11.2015
comment
Все още ли се интересувате от решение или бихте могли да го поправите сами? Настроих клиент и сървър за тестване и мога да го публикувам като отговор!? Както и да е, мога да го пусна, wsse сървърът валидира подписите без грешка.   -  person smat88dd    schedule 03.11.2015
comment
@smat88dd Мисля, че последната ми редакция го поправи чрез зареждане на подписа. Нямам контрол върху клиента, който прави заявката. Мисля, че публичният ключ, който имам, може да е невалиден, защото винаги се оценява като false. Ако вашето решение се различава от моето, все пак бих искал да го видя. Само за да има някаква документация, на която да се обърнете.   -  person soulfreshner    schedule 03.11.2015
comment
нямате контрол върху клиента? но в първоначалната си публикация казахте, че сте създали клиент с библиотеката от github.com/robrichards/wse- php и тази библиотека и включените примери подписват съобщение за сапун и включват публичен подпис. какъв различен клиент използвате сега?   -  person smat88dd    schedule 04.11.2015
comment
@smat88dd съжалявам. За пояснение: имам клиент, който прави заявка към уеб услуга. Тази част работи добре. Обработката на заявката отнема известно време. Тогава клиентът от другата страна прави заявка към моята уеб услуга. Нямам контрол върху отдалечения клиент, но трябва да създам сървъра, за да обработя заявката, и не съм сигурен дали внедрих сървъра правилно.   -  person soulfreshner    schedule 04.11.2015


Отговори (1)


Както и да е, първият ви подход ми изглежда добре, моят сървър има същата структура. За съжаление, 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);
}
?>
person smat88dd    schedule 04.11.2015
comment
О, между другото - този код наистина работи, но само когато публичният ключ на подписа е включен в сапуненото съобщение. Ако някой иска сам да предостави публичния ключ, промените в WSSESoapServer са необходими. - person smat88dd; 04.11.2015
comment
..но това изобщо не отговаря на въпроса. Целият ми проблем е със зареждането на публичния ключ за проверка на подписа. Какви промени са необходими? Все пак благодаря за помощта. Поне виждам, че съм на прав път - person soulfreshner; 04.11.2015
comment
Съжалявам, позволете ми да поясня: WSSESoapServer няма опция за зареждане на публичен ключ. Направено е за получаване на ключа от вътрешността на сапуненото съобщение. Отговорът ми беше само частичен, защото вие също бяхте попитали как да направите сървър с WSSESoapServer, защото нямаше примери. - person smat88dd; 05.11.2015
comment
ААА добре. Благодаря за това :) - person soulfreshner; 05.11.2015
comment
Всъщност отговорих на въпроса ви в моя отговор. Когато прочетете внимателно, казах, че ще трябва да промените класа WSSESoapServer, за да разрешите зареждането на публични ключове, предоставени от потребителя. - person smat88dd; 05.11.2015