В настоящее время я разрабатываю клиент 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 заканчивается «внутренней ошибкой». Я предполагаю, что это связано с отсутствием сертификатов и тому подобным. Я не уверен, есть ли способ получить дополнительную информацию из ответа, но документации об указанной ошибке нет.
Я играл с несколькими опциями и хранилищами ключей, закрытыми ключами и сертификатами в нескольких форматах, но не получил никакого положительного результата. Я думаю, все дело в том, что не отправляется правильный заголовок.
Большое спасибо.
Uncaught SoapFault exception
: [env: Client] Internal Error in ... `. Я не очень понимаю твой вопрос, ты хочешь сказать ссылку на xsd? - person wtf8_decode   schedule 22.12.2014htmlspecialchars()
или сообщите своему браузеру, что выводится текст, установив соответствующий заголовок типа содержимого (в зависимости от того, что для вас проще см. также: Как отображать XML в HTML в PHP?) - person hakre   schedule 22.12.2014php script.php
. Спасибо за ссылку, посмотрю. Часть размещенной информации выглядит многообещающей. Теперь, когда я прочитал это более внимательно, я думаю, что проблема OP несколько иная. Его проблема в том, что он не может заставить SoapClient использовать определенный URL-адрес WSDL, и ему нужно разобраться с этим. Моя проблема в том, что я не могу использовать определенную службу без передачи соответствующего заголовка. В настоящее время заголовки не отправляются. Я попробую и посмотрю, смогу ли я расширить класс SoapClient и вручную установить некоторые заголовки, но даже если это сработало, это не то, что мне нужно. - person wtf8_decode   schedule 22.12.2014header
находится внутри Параметры HTTP. Для заголовков SOAP, которые отличаются, см. Вопрос, связанный с заголовком WS-Security, , который я давал ранее. - person hakre   schedule 22.12.2014