Помогите с Exchange 2010 EWS (API) и / или PHP-библиотекой NuSOAP? - PullRequest
2 голосов
/ 18 октября 2010

Просто чтобы прояснить, прежде чем продолжить: использование встроенного в PHP класса SOAP, к сожалению, здесь не вариант (PHP производственного сервера не построен с ним и не будет).


Iпытаюсь использовать EWS, чтобы позволить мне аутентифицировать пользователей для полностью внешнего серверного приложения.Аутентификация LDAP была запрещена.Я подтвердил, что мой EWS wsdl правильный с помощью http://www.testexchangeconnectivity.com/, инструмента автообнаружения Microsoft.Содержимое WSDL можно найти здесь: http://pastebin.org/214070

Сервер использует SSL и использует метод проверки подлинности по умолчанию для EWS «NTLM».

примеры кода в Интернете, к сожалению, я не очень разбираюсь в XML, SOAP или cURL (что в значительной степени относится ко всем технологиям, которые здесь используются).Текущая итерация моего кода находится ниже:

<code><?php

include_once('./lib/nusoap.php');

$username = 'username@example.com';
$password = 'password';
$ews_url  = 'https://owa.example.com/EWS/Exchange.asmx';
$soapclient = new nusoap_client($service, true);
$soapclient->setCredentials($username, $password, 'ntlm');
$soapclient->setUseCurl(true);
$soapclient->useHTTPPersistentConnection();
$soapclient->setCurlOption(CURLOPT_USERPWD, $username.':'.$password);
$soapclient->soap_defencoding = 'UTF-8';

$params  = '<FindItem xmlns="http://schemas.microsoft.com/exchange/services/2006/messages"';
$params += ' xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" Traversal="Shallow">';
$params += '    <ItemShape>';
$params += '        <t:BaseShape>IdOnly</t:BaseShape>';
$params += '        <t:AdditionalProperties>';
$params += '            <t:FieldURI FieldURI="message:From"/>';
$params += '            <t:FieldURI FieldURI="item:Subject"/>';
$params += '            <t:FieldURI FieldURI="message:IsRead"/>';
$params += '            <t:FieldURI FieldURI="item:DateTimeReceived"/>';
$params += '            <t:FieldURI FieldURI="calendar:Start"/>';
$params += '            <t:FieldURI FieldURI="calendar:End"/>';
$params += '            <t:FieldURI FieldURI="calendar:Location"/>';
$params += '            <t:FieldURI FieldURI="task:Status"/>';
$params += '            <t:FieldURI FieldURI="task:DueDate"/>';
$params += '        </t:AdditionalProperties>';
$params += '    </ItemShape>';
$params += '    <IndexedPageItemView Offset="0" MaxEntriesReturned="5" BasePoint="Beginning"/>';
$params += '    <ParentFolderIds>';
$params += '        <t:DistinguishedFolderId Id="inbox"/>';
$params += '    </ParentFolderIds>';
$params += '</FindItem>';

$operation = 'FindItem';
$namespace = '';
$soapAction = '';
$headers = false;
$result = $soapclient->call($operation, $params, $namespace, $soapAction, $headers);
echo '<pre>'; print_r($result); echo '
';if ($ soapclient-> fault) {echo 'FAULT:';echo '
'; print_r($result); echo '
';} else {$ err = $ soapclient-> getError ();if ($ err) {echo '

Ошибка : '.$ err.'

';} else {echo 'Соединение установлено.';}}?>

Фактическая проблема, с которой я столкнулся, заключается в том, что NuSOAP возвращает общее сообщение об ошибке: «в документе WSDL не определено ни одной операции!».Судя по WSDL, это кажется неправильным и заставляет меня поверить, что я что-то упустил в коде.Если я удаляю фактический клиентский вызов в коде ($ soapclient-> call (...)), код выводит «Соединение установлено.», Но это происходит с попыткой кода аутентификации NTLM или без нее.

Я также пытался использовать проект "php-ews" на моей машине разработки (хотя тот же код не будет работать на рабочем сервере), но также не смог получить доступ к чему-либо без получения ошибки.

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

ОБНОВЛЕНИЕ 1: Кажется, одной ошибкой при загрузке WSDL является Аутентификация NTLM.Используя только cURL (без NuSOAP), я смог получить доступ к файлу WSDL и обнаружить, что сервер перенаправляет в другое местоположение конечной точки (... / EWS / Services.wsdl).

К сожалению, япопытался использовать возможность cURL библиотеки NuSOAP и установить те же параметры через NuSOAP, и я все еще получаю то же самое общее сообщение об ошибке, как будто NuSOAP просто не может увидеть / просмотреть / получить доступ к файлу WSDL.Я полагаю, что это все еще может быть аутентификация NTLM, поскольку для возврата версии cURL требуется несколько минут (NTLM - это многоэтапный процесс рукопожатия), тогда как код клиента NuSOAP немедленно возвращает сообщение об ошибке.

1 Ответ

2 голосов
/ 22 октября 2010

Есть несколько вещей, которые вы хотите посмотреть здесь.

  1. Ошибка в вашем вызове фактического soap_client. Вы определили конечную точку в переменной с именем $ ews_url, но затем вызвали конструктор с помощью $ service.

  2. Почему вы добавляете строку к строке в вашей переменной $ xml - возможно, в своей скорости вы вместо этого намеревались объединить? (операторы: + против.)

  3. Используя следующую вики-информацию, направленную на работу с EWS в Java, кажется, что Microsoft снова допустила грубую ошибку в реализации общего протокола. Модификация types.xsd в этой Wiki фактически вызывает проблему, поэтому игнорируйте это изменение, но загрузка локальной копии Services.wsdl и ее изменение для указания на ваш собственный сервер, похоже, работает правильно. http://www.bedework.org/trac/bedework/wiki/ExchangeWS текст ссылки

Следующий код должен работать, если вы загрузили локальную копию ваших types.xsd, messages.xsd и Services.wsdl и изменили файл Services.wsdl, добавив необходимую информацию, относящуюся к вашему серверу. Убедитесь, что локальные копии этих файлов находятся в одной папке на вашем сервере.

<code><?php
    include_once('./lib/nusoap.php');

    $username = 'username@example.com';
    $password = 'password';
    $endpoint = 'http://your.local.version/of/Services.wsdl';
    $wsdl = true;
    $soapclient = new nusoap_client($endpoint, $wsdl);

    $soapclient->setCredentials($username, $password, 'ntlm');

    $xml  = '<FindItem xmlns="http://schemas.microsoft.com/exchange/services/2006/messages"';
    $xml .= ' xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" Traversal="Shallow">';
    $xml .= '   <ItemShape>';
    $xml .= '       <t:BaseShape>IdOnly</t:BaseShape>';
    $xml .= '       <t:AdditionalProperties>';
    $xml .= '           <t:FieldURI FieldURI="message:From"/>';
    $xml .= '           <t:FieldURI FieldURI="item:Subject"/>';
    $xml .= '           <t:FieldURI FieldURI="message:IsRead"/>';
    $xml .= '           <t:FieldURI FieldURI="item:DateTimeReceived"/>';
    $xml .= '           <t:FieldURI FieldURI="calendar:Start"/>';
    $xml .= '           <t:FieldURI FieldURI="calendar:End"/>';
    $xml .= '           <t:FieldURI FieldURI="calendar:Location"/>';
    $xml .= '           <t:FieldURI FieldURI="task:Status"/>';
    $xml .= '           <t:FieldURI FieldURI="task:DueDate"/>';
    $xml .= '       </t:AdditionalProperties>';
    $xml .= '   </ItemShape>';
    $xml .= '   <IndexedPageItemView Offset="0" MaxEntriesReturned="5" BasePoint="Beginning"/>';
    $xml .= '   <ParentFolderIds>';
    $xml .= '       <t:DistinguishedFolderId Id="inbox"/>';
    $xml .= '   </ParentFolderIds>';
    $xml .= '</FindItem>';

    $operation = 'FindItem';
    $result = $soapclient->call($operation, $xml);
    echo '<pre>'; print_r($result); echo '
'; ?>

Кажется, что все решение заключается в наличии локальной копии основных справочных файлов SOAP и исправлении файла Services.wsdl. Если у вас был доступ к серверу Exchange, вы могли бы изменить файл Services.wsdl, и все, что могло бы работать должным образом, без всех этих хлопот. К сожалению, я не могу это проверить.

...