Добавление заголовков 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, но не могу понять, как включить всю необходимую информацию, поскольку примеры довольно простые.

Полагаю, я мог бы пойти по пути DIY и вручную создать заголовки, но я хотел бы, чтобы это было как можно проще.

Какие-нибудь подсказки?

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

В настоящее время я использую 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
Мне не удалось найти ничего, что работало бы для меня. Кажется, что большинство людей используют имя пользователя и пароль auth. Я должен отправить заголовки, подобные тем, которые описаны моим провайдером. Я не думаю, что это можно было бы рассматривать как «слишком широкое», учитывая, что вопрос довольно конкретный: генерировать заголовки, подобные показанному.   -  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] Internal Error in ... `. Я не очень понимаю твой вопрос, ты хочешь сказать ссылку на 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 использовать определенный URL-адрес WSDL, и ему нужно разобраться с этим. Моя проблема в том, что я не могу использовать определенную службу без передачи соответствующего заголовка. В настоящее время заголовки не отправляются. Я попробую и посмотрю, смогу ли я расширить класс 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