Мое приложение регулярно подключается к стороннему серверу для извлечения данных через SOAP / WSDL:
$this->soap_client = new SoapClient("https://[the-domain]:443/[path]?wsdl", array( 'trace'=>1, 'login'=>$this->username, 'password'=>$this->password, 'exceptions' => true, 'cache_wsdl' => WSDL_CACHE_NONE )
В прошлом году все было замечательно, но недавно они обновили свой файл WSDL, и теперь, когда приложение пытается подключиться, я получаю следующие две ошибки :
SoapClient::SoapClient(http://[the-domain]:80/[path]?xsd=1): failed to open stream: HTTP request failed! HTTP/1.1 401 Unauthorized
а также
SoapClient::SoapClient(): I/O warning : failed to load external entity "http://[the-domain]:80/[path]?xsd=1"
Когда я смотрю на XML-файл WSDL, кажется, что оскорбительный невыгружаемый файл является файлом схемы документа (schemaLocation), который он пытается импортировать: (из WSDL 🙂
<types> <xsd:schema> <xsd:import namespace="[irrelevant]" schemaLocation="http://[the-domain]:80/[path]?xsd=1"/> </xsd:schema> </types>
Я несколько раз бил головой об этом, и, насколько я могу судить, проблема одна из двух:
302 redirects
на https
url (и отбрасывает объявление порта). Возможно ли, что вызов SOAP не будет следовать перенаправлению при попытке импортировать схему? Предполагая, что это вторая проблема, есть ли способ заставить систему использовать другой URL-адрес схемы без загрузки файла WSDL, редактирования его и сохранения его / ссылки на него локально? Если это так, я могу попробовать передать учетные данные в URL ( http://username:password@domain....
)?
Если мой единственный снимок – создать измененную копию файла схемы WSDL и XSD, пусть будет так, но я бы хотел услышать, есть ли у кого-нибудь мысли, которые позволили бы мне избежать этого (так как схема меняет время, ко времени).
Похоже, что PHP SoapClient придерживается той же политики домена (включая схему) для отправки имени пользователя и пароля Basic Auth в запросе WSDL, который выполняется для импорта xsd-файла в схеме WDSL.
Поэтому, если URL-адрес WSDL имеет схему https
, а импорт имеет схему http
, PHP не отправляет базовую информацию аутентификации, поскольку соединение не зашифровывается больше, когда запрашивается http
адрес импорта http
(что может поставить под угрозу конфиденциальность информации аутентификации).
Однако кажется, что, по крайней мере, для некоторых версий PHP (может быть исправлено в более новых версиях) проблема аутентификации сохраняется, даже если http
адрес URL перенаправляется на https
one (в том же домене). После перенаправления на безопасный URL-адрес с тем же доменом PHP может снова включить данную базовую информацию об аутентификации.
В конце концов, единственный способ, который я нашел, чтобы исправить это, заключался в том, чтобы заставить другую сторону изменить свой контент WSDL для импорта защищенного URL ( https
one), который имеет ту же схему, домен и порт, что и сам URL WDSL.
Если это не вариант для вас, вы всегда можете найти решение, которое должно сохранить WSDL, а также импорт (я) в качестве локальных файлов и ссылаться на WDSL- файл вместо URL-адреса . Конечно, это также означало бы, что вам придется изменить WSDL, чтобы импортировать правильный локальный файл (вместо http
адреса http
) и, возможно, другой импорт. К сожалению, это единственный обходной путь, который я знаю в этом случае.
Я также нашел этот отчет об ошибке PHP, который может быть связан.
Я бы дал cURL попробовать, у него есть опция для следующих перенаправления
Как отправить запрос SOAP из PHP