Добавяне на WSSE хедъри към XML с PHP

В момента разработвам WS клиент, който трябва да подпише своите заявки, преди да ги изпрати на сървъра. Имам частен ключ и сертификат за тази цел, но се боря с хедъра за сигурност. Очакваната структура на изходния XML трябва да бъде нещо подобно:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header><wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-
1.0.xsd"><wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="CertId-45..."
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-
1.0.xsd"> ... </wsse:BinarySecurityToken><ds:Signature Id="Signature-13"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#id-14">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>62...</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
...
</ds:SignatureValue>
<ds:KeyInfo Id="KeyId-...">
<wsse:SecurityTokenReference wsu:Id="STRId-..." xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-
wss-wssecurity-utility-1.0.xsd"><wsse:Reference URI="#CertId-..." ValueType="http://docs.oasis-
open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/></wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature></wsse:Security></soapenv:Header>
<soapenv:Body wsu:Id="id-14" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 

Опитах да използвам xmlseclibs, но не мога да разбера как да включа цялата необходима информация, тъй като примерите са доста основни.

Предполагам, че бих могъл да отида по пътя „направи си сам“ и ръчно да изградя заглавките, но бих искал да го запазя възможно най-прост.

Някакви улики?

Допълнителна информация

В момента използвам SoapClient за тази задача. Работата е там, че не знам как да направя това точно. XML, който изпращам, изисква подписване на съдържанието му и аз го направих ръчно (използвайки функция c14n и изчислявайки нейния дайджест ..). Въпреки това, за да направя същото за цялото тяло, ще ми трябва достъп до необработения XML (предполагам), така че не мисля, че това ще работи.

Не съм опитвал да създавам SOAP заглавки ръчно, тъй като се опитвам да избегна всякакви хакове. Търся нещо, което е едновременно лесно за изпълнение и лесно за работа.

Моят код в момента изглежда така (свеждайки го до минимум за по-добра четливост):

$context = stream_context_create(array(
    'ssl' => array(
        'verify_peer' => false,
        'allow_self_signed' => true,
        'ciphers'=>'SSLv3'
    )
));

$client = new SoapClient($url, array(
    //'connection_timeout' => 100,
   /* 'passphrase' => $pass,

    'local_cert' => $keystore,*/
    'stream_context' => $context,
   // 'connection_timeout' => 1,
    'trace' => true, 
    'exceptions' => true
));

$soapBody = new \SoapVar($xml, \XSD_ANYXML);

try{
    $client->__soapCall('SOMEACTION', array($soapBody));
}
catch (SoapFault $exception) {
        echo $exception->getMessage();

    }

Променливата xml съдържа XML код, който знам, че е правилен. Тестван е както на SoapUI (където трябваше да предоставя своите ключове и парола), така и на онлайн услуга за тестване, предоставена от моя доставчик. Това означава, че изпратените данни са 100% верни.

Моят PHP код обаче завършва с „Вътрешна грешка“. Предполагам, че е свързано с липсата на сертификати и други подобни. Не съм сигурен дали има начин да получа повече информация от отговора, но няма документация за споменатата грешка.

Играх си с няколко опции и хранилища за ключове, частни ключове и сертификати в няколко формата, без да получа положителен резултат. Мисля, че всичко е свързано с факта, че не се изпраща правилният хедър.

Благодаря много.


person wtf8_decode    schedule 19.12.2014    source източник
comment
Тук не искаш много. Не е ясно кои грешки получавате, нито какво конкретно работи. Така че всъщност въпросът ви изглежда твърде широк. Съществуващ материал как да създадете и добавите WSSE заглавки с PHP всъщност дори съществува на този уебсайт, така че не е абсолютно ясно какво точно питате тук, тъй като според текста в заглавието този въпрос е бил задаван и преди, но вие да подчертае какво го прави различен от съществуващия материал. Освен това може дори да не се нуждаете от никакви заглавки, тъй като сертификатите се обработват на транспортния слой над SOAP.   -  person hakre    schedule 19.12.2014
comment
Не успях да намеря нищо, което да ми свърши работа. Повечето хора изглежда използват удостоверяване с потребителско име и парола. Трябва да изпратя заглавки като тези, описани от моя доставчик. Не мисля, че може да се разглежда като „твърде широко“, като се има предвид, че въпросът е доста конкретен: генерирайте заглавки като показаните.   -  person wtf8_decode    schedule 19.12.2014
comment
Можете ли вече да създадете XML подпис? Вече можете ли да създавате SOAP заглавки и успяхте ли да проверите това спрямо отдалечената система? Как изглежда текущият ви код? Коя грешка получавате от отдалечената система? Какво казва документацията на отдалечената система за съобщението за грешка или кода, който получавате? Какво сте опитвали, за да отстраните проблема досега?   -  person hakre    schedule 19.12.2014
comment
Обядвам, ще добавя информация при първа възможност   -  person wtf8_decode    schedule 19.12.2014
comment
Не бързайте, по-важно е да ядете бавно :)   -  person hakre    schedule 19.12.2014
comment
Добавих още информация (не съм сигурен дали сте я виждали).   -  person wtf8_decode    schedule 22.12.2014
comment
Тъй като имате 'trace' =› true, можете да проверите кой XML е изпратен до сървъра (и кой отговор сте получили). Това често съдържа повече информация/подсказки, отколкото само съобщението за изключение като вътрешна грешка. И можете ли да предоставите някакви технически подробности/справочна документация за кой вид подписване на заявка се отнасяте, на кой слой след коя (W3C/IETF) спецификация?   -  person hakre    schedule 22.12.2014
comment
Ще трябва да опитам да отпечатам необработения отговор, но той не се отпечатва на екрана. Ако обработя грешката и отпечатам нейното съобщение, получавам точно това. Ако оставя нещата да се сринат и премахна блока try catch, това е, което получавам Uncaught SoapFault exception: [env:Client] вътрешна грешка в ...`. Наистина не разбирам въпроса ви, искате ли да кажете, че искате връзка към xsd?   -  person wtf8_decode    schedule 22.12.2014
comment
гледате ли изхода в браузъра си? Ако е така, трябва да кодирате необработените данни за заявка или отговор като HTML, преди да ги покажете, напр. с htmlspecialchars() или кажете на браузъра си, че изходът е текст, като зададете съответно заглавката тип съдържание (което от двете е по-лесно за вас , вижте също: Как да покажа XML в HTML в PHP?)   -  person hakre    schedule 22.12.2014
comment
А за заглавките на WS-Security решението в stackoverflow.com/a/6677930/367456 изглежда е прието и работи.   -  person hakre    schedule 22.12.2014
comment
Изпълнявам скрипта си през конзолата като php script.php. Благодаря за линка, ще го погледна. Част от публикуваната информация изглежда много обещаваща. Сега, когато го прочетох по-подробно, мисля, че проблемът на OP е доста различен. Неговият проблем е, че не може да накара SoapClient да използва определен WSDL URL адрес и трябва да разреши това. Проблемът ми е, че не мога да използвам определена услуга, без да предам подходящата заглавка. В момента не се изпращат заглавки. Ще се опитам да видя дали мога да разширя класа SoapClient и ръчно да задам някои заглавки, но дори и да проработи, не е това, което преследвам.   -  person wtf8_decode    schedule 22.12.2014
comment
Имате предвид SOAP заглавки или HTTP заглавки? За HTTP заглавки можете да направите това чрез потока $context, който вече използвате за SSL опции, header е вътре в HTTP опции. За SOAP заглавки, които са различни, вижте въпроса, свързан с заглавката на WS-Security зададох по-рано.   -  person hakre    schedule 22.12.2014