Доступ к веб-службам Exchange с помощью PHP и cURL
Здравствуйте,
В настоящее время я пишу клиент для доступа к серверу Microsoft Exchange и чтения из него контактов, встреч и т.д.
Через дни поиска я смог подключиться к EWS через клиент PHP Soap и собственную обертку HTTPS Stream. Этот сайт очень помог мне на этом этапе.
Все работало отлично на моей машине Windows 7 с помощью XAMPP
Теперь я загрузил свой проект на машину разработки Debian 6.0 Squeeze, которая имеет точно такую же конфигурацию, что и моя компьютер с Windows, относительно настроек веб-сервера, php, настроек mysql и т.д., но это просто больше не работает
Машина debian может без проблем разрешать и пинговать сервер обмена
Я прикрепил фактическую проблему до точки, где cURL не может получить WSDL файл EWS
Он всегда получает пустой ответ и код состояния 401 (неавторизованный)
Учетные данные, которые я использую, верны, одни и те же учетные данные работают на моей машине Windows
Я извлек неисправный кусок кода и попытался запустить его автономно, он выглядит так:
echo "Trying to get https://".$cfg[ 'Exchange.Server' ]."/EWS/Services.wsdl<br>";
$curl = curl_init( 'https://'.$cfg[ 'Exchange.Server' ].'/EWS/Services.wsdl' );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1 );
curl_setopt( $curl, CURLOPT_HTTPAUTH, CURLAUTH_NTLM );
curl_setopt( $curl, CURLOPT_USERPWD, $cfg[ 'Exchange.User' ].':'.$cfg[ 'Exchange.Password' ] );
curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $curl, CURLOPT_SSL_VERIFYHOST, false );
echo '<pre>';
$response = curl_exec( $curl );
$info = curl_getinfo( $curl );
var_dump( $info );
var_dump( $response );
curl_close( $curl );
В результате я получаю упомянутый код состояния 401 и пустой ответ
Когда я вызываю тот же url в моем браузере или с тем же кодом на моей машине Windows, я получаю файл WSDL, который я хочу
На самом деле я даже не могу сказать, является ли это проблемой на основе Linux или если я что-то делаю неправильно в какой-то момент, я боюсь с этим в течение 2 дней.
Есть ли кто-то, кто может найти мою ошибку или сказать мне причину, почему она не работает?
Я могу предоставить любую дополнительную необходимую информацию по запросу
Ответы
Ответ 1
Если вы правильно инициализируете свой soap-клиент, вы должны предварительно запрограммировать запросы на запросы следующим образом:
$curl = curl_init($location); //'https://'.$server_address.'/EWS/Exchange.asmx'
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); //valid soap headers with keep-alive
curl_setopt($ch, CURLOPT_POST, true );
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_USERPWD, $user.':'.$password);
$response = curl_exec($curl);
Что касается вашего кода, попробуйте прокомментировать следующую строку:
curl_setopt( $curl, CURLOPT_HTTPAUTH, CURLAUTH_NTLM );
Также посмотрите, где эта оболочка работает в вашей настройке:
http://ewswrapper.lafiel.net/
Если это так, посмотрите на классы SOAP, используемые там - он использует php встроенный в качестве базы.
Почему вы не можете хранить файл wsdl локально в любом случае?
UPDATE:
Хорошо, я играл с этим в своем боксе Debian, и это работает для меня безупречно:
$domain = 'xxxxxx';
$user = 'xxxxxx';
$password = 'xxxxxx';
$ch = curl_init('https://'.$domain.'/EWS/Services.wsdl');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_USERPWD, $user.':'.$password);
$response = curl_exec($ch);
$info = curl_getinfo( $ch );
$error = curl_error ($ch);
print_r(array($response,$info,$error));
возвращает
Array
(
[0] => <?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions
(...)
</wsdl:definitions>
[1] => Array
(
[url] => xxxxx/EWS/Services.wsdl
[content_type] => text/xml
[http_code] => 200
[header_size] => 250
[request_size] => 147
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0.60574
[namelookup_time] => 0.165249
[connect_time] => 0.268173
[pretransfer_time] => 0.474009
[size_upload] => 0
[size_download] => 55607
[speed_download] => 91800
[speed_upload] => 0
[download_content_length] => 55607
[upload_content_length] => 0
[starttransfer_time] => 0.580931
[redirect_time] => 0
[certinfo] => Array
(
)
[redirect_url] =>
)
[2] =>
)
Ответ 2
Ваша первая проверка не должна использовать сложные сценарии.
Вместо этого попробуйте открыть WDSL из простого окна браузера на машине Debian следующим образом:
https://your.exchange-server.com/EWS/Services.wsdl
Если это не работает, вероятно, существуют ограничения доступа, которые зависят от клиентской IP-сети или сети клиента (например, ваша машина разработки находится в надежной сети, а не в Debian). Тот факт, что вы получаете запрос 401 ( "Несанкционированный", требует аутентификации пользователя) предполагает, что нет проблем с контактом с сервером, но с проверкой подлинности.
Еще одна проверка, которую я предлагаю, заключается в том, что вы заглянули в свой phpinfo(), чтобы убедиться, что ваша установка PHP на Debian способна обрабатывать запросы HTTP * S *. Убедитесь, что установлен OpenSSL!
Ответ 3
Эта статья помогла мне в правильном направлении. Следует иметь в виду, что
ваша установка PHP может не использоваться для настройки вашей системы cURL/libcurl.
http://blog.ianty.com/ubuntu/exchange-web-services-ews-ntlmv2-and-linux/