401 ошибка проверки подлинности при попытке SoapClient извлечь файл схемы

мое приложение обычно подключается к стороннему серверу для получения данных через 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>

Я бил головой об это некоторое время, и, насколько я могу судить, проблема заключается в одной из двух вещей:

  1. когда я загружаю этот URL-адрес схемы в браузере (после аутентификации браузера), это 302 redirects до https url (и отбрасывает объявление порта). Возможно ли, что SOAP-вызов не будет следовать перенаправлению, когда попытка импортировать схему?
  2. учитывая тот факт, что сообщение об ошибке является ошибкой 401 - возможно ли, что вызов SOAP не передает учетные данные при попытке импорта схемы? Файл схемы требует такой же проверки подлинности, как и файл WSDL, но, возможно, сервер не расширяет проверку подлинности на схему при попытке импорта?

предполагая, что это вторая проблема, есть ли способ заставить систему использовать другой URL-адрес схемы без загрузки файла WSDL, его редактирования и хранения/ссылки на него локально? Если это так, я могу попробовать передать учетные данные в URL (http://username:password@domain....)?

если мой единственный шанс-создать измененную копию файла схемы WSDL и XSD, так и быть, но я хотел бы услышать, Есть ли у кого-нибудь мысли, которые позволили бы мне избежать этого (поскольку схема время от времени меняется).

2 ответов


похоже, что PHP SoapClient придерживается та же политика домена (включая схему) для отправки основного имени пользователя и пароля Auth в запросе WSDL, который выполняется для импорта xsd-файла в схеме WDSL.

Итак, если url WSDL имеет https схема и импорт имеет http scheme, PHP не отправляет основную информацию аутентификации, так как соединение больше не шифруется при запросе http импорт url (который скомпрометирует конфиденциальность информации аутентификации).

однако кажется, что по крайней мере для некоторых версий PHP (может быть исправлена в более новых версиях) проблема аутентификации сохраняется, даже если http url перенаправляет на https one (в том же домене). после перенаправления на безопасный URL с тем же доменом PHP может снова включить заданную базовую информацию об аутентификации.

решение

в конце концов, единственный аккуратный способ, который я нашел, чтобы исправить это заставлял другую сторону изменять содержимое WSDL для импорта безопасного URL-адреса (https one), который имеет ту же схему, домен и порт, что и сам url WDSL.

решение

если это не вариант для вас, конечно, вы всегда можете пойти на обходной путь, который должен сохранить WSDL, а также импорт(ы) в качестве локальных файлов и обратиться к WDSL вместо URL-адресом. Конечно, это также означает, что вам придется изменить WSDL для импорта правильного локального файла (вместо http URL), а также, возможно, другие импорта. К сожалению, это единственный обходной путь, который я знаю в этом случае.


ошибка PHP?

Я нашел это отчет об ошибке PHP что может быть связано.


Я бы дал cURL попробовать, у него есть возможность для следующих перенаправлений

как опубликовать запрос SOAP из PHP