2015-10-01 4 views
19

Я пытаюсь вызвать службу WCF (.NET) из PHP. Это немного сложнее, чем просто использование SoapClient, поскольку для аутентификации используется служба WS2007FederationHttpBinding.Вызов службы WCF с PHP (с федеративной безопасностью)

Вот код, который я использую в данный момент. Я даже не добавил учетные данные, поскольку я не уверен, как, но независимо от того, я даже не в том месте, где я получаю доступ к отказам в ошибках.

$wsdl = "https://slc.centershift.com/sandbox40/StoreService.svc?wsdl"; 
$client = new SoapClient($wsdl,array(
     //'soap_version'=>SOAP_1_2 // default 1.1, but this gives 'Uncaught SoapFault exception: [HTTP] Error Fetching http headers' 
     )); 
$params = array(); 
$params['SiteID'] = 123; 
$params['GetPromoData'] = false; 

$ret = $client->GetSiteUnitData(array('GetSiteUnitData_Request'=>$params)); 
print_r($ret); 
  1. Какой WSDL я должен указывать на?

  2. Нужно ли указывать SOAP 1.2? Когда я это сделаю, я получаю таймаут соединения ([HTTP] Error Fetching http headers). Когда я этого не делаю, используется значение по умолчанию для SOAP 1.1, и я получаю [HTTP] Cannot process the message because the content type 'text/xml; charset=utf-8' was not the expected type 'application/soap+xml; charset=utf-8'. Это потому, что я еще не аутентифицирован, или потому, что я использую неправильную версию SOAP?

  3. Как проверить подлинность на PHP? Вот соответствующий код .NET/C#. Нужно ли мне как-то ставить их как заголовки SOAP? Или я думаю о том, что все это неправильно, и мне нужно сделать некоторую аутентификацию, прежде чем я даже вызову метод (из того, что я прочитал, я должен вернуть токен, а затем использовать его для всех будущих вызовов метода - I Кажется, я вижу пример этого в an answer here on Stack Overflow.

Если я позвоню $client->__getFunctions(), используя либо WSDL и SOAP либо версии, я получаю правильный список всех функций, поэтому я предполагаю, что любой из них и моя настоящая проблема - это аутентификация.

Другие программисты, с которыми я говорил, потратили время на то, чтобы заставить это работать, но отказались и вместо этого внедрили прокси-сервер в .N ET. Они передают свои параметры с PHP на свою незащищенную службу .NET, которая, в свою очередь, вызывает этот безопасный сервис. Он работает, но кажется безумно неэффективным для меня и контрпродуктивным, поскольку цель WCF заключается в поддержке всех типов клиентов (даже не-HTTP-файлов!).

Я прочитал How to: Create a WSFederationHttpBinding на MSDN, но это не помогло.

+0

Либо? Wsdl или? SingleWsdl будет в порядке. Первый ссылается на несколько документов, разделенных по назначению, последний имеет все в одном месте. Wsdl указывает, что используется мыльная версия, поэтому кажется странным, что после того, как она загрузила wsdl, все равно нужно сказать, какую версию мыла использовать. Я предлагаю, чтобы библиотека была незрелой/плохой, если эта базовая информация должна быть предоставлена ​​в дополнение к wsdl, и я бы не ожидал, что вы с ней начнете работать. Я предлагаю найти другую/лучшую библиотеку мыла. – MattC

+0

@MattC Спасибо за комментарий. Полезно знать о WSDL, но, надеюсь, мыльная библиотека не является проблемой (это родной PHP-файл). Я проверил nuSoap, но не выглядел так, как будто он принесет какие-либо преимущества. –

+0

Я действительно не хочу звучать snarky, @ShaneN, но встроенный в PHP не является гарантией качества. См. crappy 'mail()'. Не работали с SOAP с PHP, поэтому я не могу помочь. – Palec

ответ

0
  1. Вы можете использовать этот URL для WSDL https://slc.centershift.com/Sandbox40/StoreService.svc?singleWsdl. Этот WSDL имеет все определения.

  2. Вы должны использовать 1.2, потому что этот веб-сервис работает с версией SOAP 1.2. Я попробовал его с 1.1 и 1.2, и обе они дали ошибку. 1.1 - ошибка версии, 1.2 - ошибка таймаута. Я думаю, что на этом тестовом сервере есть ошибка. Я использовал его с svcutil для генерации кода, но он тоже ошибся. Нормальный он должен получать информацию и генерировать пример кода для вызова службы.

  3. Обычно вы можете добавлять параметры аутентификации с помощью SoapHeader или напрямую добавлять в опции в SoapClient consruct (если аутентификация службы является базовой аутентификацией). Я пишу ниже код в соответствии с вашим снимком экрана. Но он дает время ожидания после долгого ожидания.

    $wsdl = "https://slc.centershift.com/sandbox40/StoreService.svc?wsdl"; 
    $client = new SoapClient($wsdl,array('trace' => 1,'soap_version' => SOAP_1_2)); 
    
    $security = array(
    'UserName' => array(
        'UserName'=>'TestUser', 
        'Password'=>'TestPassword', 
        'SupportInteractive'=>false 
    ) 
    ); 
    
    $header = new SoapHeader('ChannelFactory','Credentials',$security, false); 
    $client->__setSoapHeaders($header); 
    
    
    
    $params = array(); 
    $params['SiteID'] = 100000000; 
    $params['Channel'] = 999; 
    try { 
        $ret = $client->GetSiteUnitData($params); 
        print_r($ret); 
    }catch(Exception $e){ 
        echo $e->getMessage(); 
    } 
    

    __getFunctions работы, потому что он печатает функции, определенные в WSDL. Нет никакой проблемы с получением информации WSDL при первом вызове. Но реальной проблемой является общение. PHP получает WSDL, генерирует требуемый SOAP-запрос, затем отправляет сервер, но сервер не отвечает правильно. Сервер SOAP всегда дает ответ, даже если параметры или тело запроса неверны.

    Вам следует установить связь с поставщиком услуг, я думаю, что они могут дать четкий ответ на ваши вопросы.

+0

Большое спасибо за ответ. К сожалению, поставщик услуг не желает оказывать помощь. Они утверждают, что их служба работает для .NET-клиентов, поэтому у них нет причин расследовать это, не работая ни на какие другие типы клиентов. По сути, они заставляют нас использовать стек Microsoft, который мы не можем делать только для них. –

0

Если вызов SOAP работает с C# приложения, вы можете использовать Wireshark (с фильтром ip.dst == 204.246.130.80), чтобы просмотреть фактический запрос, вносимый, а затем построить подобный запрос от PHP.

Проверьте this answer, чтобы узнать, как вы можете сделать пользовательский вызов SOAP.

Существует также возможность делать сырые запросы на завивки, поскольку может быть проще создать ваше тело xml, но тогда вам придется проанализировать ответ самостоятельно с помощью simplexml.

+0

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

+0

Если он не работает на http то самый простой способ просмотра пакетов - установить прокси-сервер для подключения и использовать [Fiddler] (http://www.telerik.com/fiddler/web-traffic-recording) в качестве прокси-сервера для захвата и просмотра данные. – Catalin

1

Работая с потреблением .NET WS от PHP, прежде чем я полагаю, что вам нужно будет создавать объекты из классов в PHP, которые соответствуют именам, ожидаемым .NET. WSDL должен рассказать вам о типах, которые он ожидает. Надеюсь, это поможет вашему пути!

Смежные вопросы