it-roy-ru.com

Подключение к https Host с помощью soapclient: как исправить проблемы с SSL?

TLDR

Я не могу подключиться к конечной точке https с SoapClient. Поскольку мой wget возвращает handshake failure, я подозреваю, что это является причиной. 

Как я могу сделать запрос SOAP к этому серверу с помощью PHP?

полный

Я пытаюсь подключиться к серверу SOAP (https). У него нет аутентификации по сертификату клиента, поэтому соединение должно быть довольно простым, но, к сожалению, это не так.

Проблема в том, что я продолжаю получать сообщения Could not connect to Host.

Метод подключения, который я использую, работает для другого сервера, и я проверил, что я правильно устанавливаю местоположение для этого сервера (изменил его на сервер, которым я управляю, и я получаю ответ там). Я подозреваю, что проблема с подключением https/ssl к серверу.

Ситуация

  • Я создаю PHP Soapclient на основе локального wsdl. 
  • Если я изменяю конечную точку, я получаю заголовки Request и Response, и все работает как положено.
  • компьютер доступен с моего сервера, хотя при подключении к нему wget возникает видимая проблема (см. ниже) Невозможно установить соединение SSL.
  • Проблема также видна с соединениями openssl (см. Ниже)

Что я пробовал.

Есть много тем о том, что «нет соединения!», Но, очевидно, много говорится о том, что «мой маршрутизатор был неисправен, я сделал опечатку в адресе и т.д.». Я попробовал эти настройки, которые были предложены несколько раз, но скорее как решение «cut'n'paste», чтобы быть уверенным, что это не сработало », а не по реальным соображениям. Некоторые комментарии от меня добавили

Создание stream_context для параметров wsdl. я пытался

$context = stream_context_create(
              array(
                'ssl' => array(
                           'verify_peer' => false,  //default
                           'allow_self_signed' => true, //needs verify peer, tried that
                           'ciphers'=>"SHA1", // quite random.
                   ),
                'https' => array(
                           'curl_verify_ssl_peer'  => false,
                           'curl_verify_ssl_Host'  => false
                          )
      )
            );
$options['stream_context'] = $context;

(сначала только параметры ssl с verify_peer и allow_self_signed. Затем я добавил массив https, затем, наконец, я добавил ключ ciphers в ssl.)

Я нашел ссылку на эту ошибку , но 1) я не получаю это предупреждение, 2) кажется, что он связан с прокси и 3) моя версия больше не должна иметь ошибку. Я бегу php 5.3.10

Когда я пытаюсь получить URL, я получаю:

    wget https://[[servername]]/SOAP
    Resolving [[servername]] ([[servername]])... xxx.xxx.xxx.xxx
    Connecting to [[servername]]([[servername]])|xxx.xxx.xxx.xxx|:443... connected.
    OpenSSL: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

Если я пытаюсь соединиться с openssl, я получаю это:

$ openssl s_client -connect [[server]]:443 -state
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:unknown state
SSL3 alert read:fatal:handshake failure
SSL_connect:error in unknown state
3074463944:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:724:

но если я заставлю ssl3, я получу ожидаемый результат

$ openssl s_client -ssl3 -connect [[server]]:443 -state
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv3 write client hello A
SSL_connect:SSLv3 read server hello A
**happy certificate stuff. this is good**
Protocol  : SSLv3
Cipher    : DHE-RSA-AES256-SHA
**more happy certificate stuff. **

Я попытался добавить curl-wrapper из этого вопроса с ssl_version, установленным в 3 (так как это похоже на работу с командой openssl выше). Эта обёртка отбрасывает некоторые параметры, поэтому я не уверен, насколько полно это будет. Кроме того, я все еще получаю ошибку рукопожатия, если я не установил проверку на false. Если я сделаю это (см. Ниже), я получу пустой ответ.

curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, false);

Причины

Как уже говорилось выше, я подозреваю, что рукопожатие SSL, но я понятия не имею, как это исправить. Я не подозреваю проблем с wsdl или созданием клиента, так как соединение работает с другим wsdl, тем же wsdl с другим набором местоположений и т.д. Именно эта конечная точка (https) вызывает у меня головную боль.

Дополнительные тесты.

Так же, как и в предыдущем тесте с curl-оберткой, я попытался отправить минимальный мыльный конверт, как, по-видимому, @halfwarr предлагает в комментариях. Алс возвращает пустой ответ.

Таким образом, с вышеизложенным кажется, что у меня есть метод выдавливания http 204 из сервера, но это вряд ли успех. Но это может быть второй проблемой? Точно сказать не могу.

Я предполагаю, что мне нужно попробовать и заставить ssl3, но я понятия не имею, как (и это может быть неправильный путь, поэтому я пытаюсь не иметь проблема XY здесь :)

12
Nanne

Интересно. Попробуйте добавить это:

wget https://[[SERVER]]/soap/ —post-file=request.xml —header=”Content-Type: text/xml” -O response.xml

Это сохранит результат в файл с именем response.xml.

1
Matheno

Последняя версия PHP 5.5.3 позволит вам установить версию SSL. Я видел других, которые могли использовать stream_context, но я также не смог получить эту работу. 

Как обходной путь и отказоустойчивость, я использовал уловку, чтобы получить запрос мыльного конверта (аналогично тому, что вы тестировали выше): 

$xml = $client->__getLastRequest()

и отправьте через curl: 


curl_setopt($ch, CURLOPT_SSLVERSION, 3);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

Это позволяет мне, по крайней мере, двигаться вперед. 

1
rdizzle

Вы включили php_openssl.dll в свой php.ini?

Ссылка:

PHP SOAP не может подключиться к источнику SSL WSDL

0
Sid