#php #web-services #soap #https #nusoap
#php #веб-сервисы #soap #https #nusoap
Вопрос:
Я застрял с этим в течение нескольких дней, и, похоже, нигде не могу найти ответ, хотя я думаю, что это довольно распространенная задача. Кто-нибудь может помочь?
Я пытаюсь использовать PHP и NuSOAP для подключения к веб-сервису. Веб-сервис требует от меня как использования ssl-сертификата, так и передачи параметров аутентификации в запросе soap. По словам администраторов веб-сервиса, запрос должен выглядеть следующим образом:
<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<o:Security xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:UsernameToken>
<o:Username>username</o:Username>
<o:Password>password</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body>
<PriceQuote xmlns="a_url">
<PartnerProfileId>a_unique_partner_id_we_have</PartnerProfileId>
<Reservation xmlns:d4p1="another_url" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
* a bunch of stuff
</Reservation>
</PriceQuote>
</s:Body>
</s:Envelope>
Я пытался выяснить, как это сделать с помощью NuSOAP. Прямо сейчас, это то, что у меня есть (я не знаю, как передать параметры аутентификации или использовать файлы сертификатов, которые у меня есть):
$client = new nusoap_client("https://endpoint_url");
$client->soap_defencoding = 'UTF-8';
$result = $client->call("PriceQuote", "");
// For debugging
echo '<h2>Request</h2>';
echo '<pre>' . htmlspecialchars($client->request, ENT_QUOTES) . '</pre>';
echo '<h2>Response</h2>';
echo '<pre>' . htmlspecialchars($client->response, ENT_QUOTES) . '</pre>';
echo '<h2>Debug</h2>';
echo '<pre>' . htmlspecialchars($client->debug_str, ENT_QUOTES) . '</pre>';
Используя приведенный выше отладочный код, я вижу, что это ответ, который я получаю от веб-службы:
HTTP/1.1 500 Internal Server Error
Date: Mon, 02 May 2011 13:42:14 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Type: text/xml; charset=utf-8
Content-Length: 347
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
a:InvalidSecurity
</faultcode>
<faultstring xml:lang="sv-SE">
An error occurred when verifying security for the message.
</faultstring>
</s:Fault>
</s:Body>
</s:Envelope>
Этот ответ, конечно, неудивителен, поскольку я не передаю никаких параметров аутентификации в запросе.
Кто-нибудь знает, как я могу передать имя пользователя и пароль в заголовке запроса SOAP, а также как я использую имеющиеся у меня файлы ssl-сертификатов? Как вы, вероятно, можете сказать, я довольно новичок в веб-сервисах и NuSOAP. Если что-то в моем вопросе не имеет смысла, пожалуйста, дайте мне знать.
Ответ №1:
если вам не нужен nu_soap, вы можете решить проблему с помощью приведенного ниже скрипта
<?PHP
$client = new SoapClient("http://Your Wsdl Location", array("trace" => 0));
$HeaderSecurity = array("UsernameToken"=>array("Username"=>"YourUserName",
"Password"=>"YourPassword",
)
);
$header[] = new SoapHeader("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd","Security",$HeaderSecurity);
$client->__setSoapHeaders($header);
//$client->__setLocation("https://YourTargetLocation/"); if you have wsdl file you don't need to use this line
$REsponse = $client->YourRequest();
?>
Комментарии:
1. Спасибо за быстрый ответ, Мустафа. Используя это (слегка измененное, поскольку я работаю без файла wsdl) Я по-прежнему получаю сообщение об ошибке: Неустранимая ошибка: неперехваченное исключение SoapFault: [a: InvalidSecurity] Произошла ошибка при проверке безопасности сообщения. Может ли это быть связано с тем, что я все еще не использую файлы ssl-сертификата? Если да, знаете ли вы, как я могу их включить?
2. может быть, вы можете попробовать передать прямую строку xml (это для nu_soap):
$client->call('MethodName',$RequestXml,NULL,"MethodName",NULL,NULL,"document");
передайте xml в$RequestXml
и введите имена ваших методов в example.3. Спасибо! Я изменил ваше предложение, чтобы также включить заголовок xml:
$result = $client->call("PriceQuote",$RequestBody,NULL,"PriceQuote",$RequestHeader,NULL,"document");
. Это выдало мне новую ошибку: … Несоответствие ContractFilter в EndpointDispatcher. Это может быть либо из-за несоответствия контракта (несовпадающих действий между отправителем и получателем), либо из-за несоответствия привязки / безопасности между отправителем и получателем. Убедитесь, что отправитель и получатель имеют одинаковый контракт и одинаковую привязку (включая требования безопасности, например, сообщение, транспорт, Нет). Может ли это быть из-за отсутствия сертификатов SSL?4. К сожалению, нет : ( Но это не что-то известное или для чего вы не найдете документацию в Интернете.
5. Оказывается, окончательные ошибки были вызваны тем, как был отформатирован запрос soap (веб-службе не понравилось форматирование, и она ответила внутренней ошибкой сервера). Предложение Мустафы в комментариях действительно помогло! В конце я использовал его метод.