使用PHP和cURL访问Exchange Web服务

时间:2011-10-05 16:00:51

标签: php curl ntlm exchangewebservices http-status-code-401

您好,

我目前正在编写一个客户端来访问Microsoft Exchange服务器并从中读取联系人,约会等。

通过几天的搜索,我已经能够通过PHP的Soap客户端和自定义HTTPS流包装器连接到EWS。 This网站在这一点上给了我很大的帮助。

使用XAMPP

在我的Windows 7机器上一切正常

现在我将我的项目上传到Debian 6.0 Squeeze开发机器,它与我的Windows机器完全相同,关于web服务器,php设置,mysql设置等等,但它不再适用了

debian机器可以毫无问题地解析和ping交换服务器

我将实际问题解决到一定程度,其中cURL无法检索EWS的WSDL文件

它始终收到空响应和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天。

是否有人可以找到我的错误或告诉我为什么它不起作用?

我可以根据需要提供任何其他所需信息

3 个答案:

答案 0 :(得分:8)

如果您正确初始化您的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文件呢?


<强>更新

好的,我在我的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] => 
)

答案 1 :(得分:1)

您的首次检查不应使用任何复杂的脚本。 而是尝试从Debian机器上的简单浏览器窗口打开WDSL,如下所示: https://your.exchange-server.com/EWS/Services.wsdl

如果这不起作用,则可能存在依赖于客户端IP或客户端网络的访问限制(例如,您的开发计算机位于受信任的网络中,而您的Debian不受此限制)。您获得401(“未授权” - 请求需要用户身份验证)这一事实表明,联系服务器但身份验证没有问题。

我建议的另一个检查是你要查看你的phpinfo(),以确保你在Debian上的PHP安装能够处理HTTP * S *请求。确保已安装OpenSSL!

答案 2 :(得分:1)

本文帮助我指出了正确的方向。要记住的一件事是 您的PHP安装可能无法共享系统的cURL / libcurl设置。

http://blog.ianty.com/ubuntu/exchange-web-services-ews-ntlmv2-and-linux/