使用 PHP 和 cURL 访问 Exchange Web 服务

发布于 2024-12-07 23:39:59 字数 1614 浏览 0 评论 0原文

您好,

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

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

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

现在我将我的项目上传到 Debian 6.0 Squeeze 开发机器,该机器在 Web 服务器、php 设置、mysql 设置等方面与我的 Windows 机器具有完全相同的配置,但它无法工作 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 的问题还是我在某个时候做错了什么,我已经为此苦苦挣扎了两天。

有人可以找到我的错误或告诉我它不起作用的原因吗?

我可以根据需要提供任何进一步需要的信息

Hello,

I am currently writing a client to access a Microsoft Exchange server and read contacts, appointments etc. from it.

Through days of searching I've been able to connect to the EWS via PHP's Soap client and a custom HTTPS Stream wrapper. This website helped me greatly at this point.

Everything worked fine on my Windows 7 machine using XAMPP

Now I uploaded my project to a Debian 6.0 Squeeze development machine that has exactly the same configuration as my Windows machine regarding the web-server, php settings, mysql settings etc. but it just wont work anymore

The debian machine can resolve and ping the exchange server without problems

I nailed the actual problem down to a point, where cURL isn't able to retrieve the WSDL file of the EWS

It always receives an empty response and a 401 (Unauthorized) status code

The credentials I use are correct, the same credentials work on my windows machine

I extracted the faulty piece of code and tried running it stand-alone, it looks like this:

    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 );

The result I receive here is the mentioned 401 status code and an empty response
When I call the same url in my browser or with the same code on my windows machine, I get the WSDL file I want

Actually I can't even tell if this is a linux-based problem or if I do something wrong at some point, I'm struggling with this for 2 days now.

Is there someone that may be able to find my mistake or tell me the reason why it doesn't work?

I may provide any further needed information on demand

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

乖乖 2024-12-14 23:39:59

如果您正确初始化您的肥皂客户端,您应该能够以这种方式执行任何请求:

$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] => 
)

If you initialize your soap client properly, you should be able to preform any requests requests this way:

$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);

As to your code, try commenting out following line:

curl_setopt( $curl, CURLOPT_HTTPAUTH, CURLAUTH_NTLM );

Also take a look wherever this wrapper works on your setup:
http://ewswrapper.lafiel.net/
If it does, take a look at SOAP classes used there - it uses php built-in as base.

Why can't you store wsdl file locally anyways?


UPDATE:

Ok, I played around with this in my Debian box and this works for me flawlessly:

$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));

returns

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] => 
)
何处潇湘 2024-12-14 23:39:59

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

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

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

Your first check should not use any complex scripting.
Instead try opening the WDSL from a simple browser window on the Debian machine like so:
https://your.exchange-server.com/EWS/Services.wsdl

If that does not work there are probably access restrictions in place that depend on the client IP or client network (e.g. your development machine being in a trusted network, your Debian not). The fact that you get a 401 ("Unauthorized" - request requires user authentication) suggests that there is no problem with contacting the server but with authentication.

Another check I suggest is that you have a look into your phpinfo() to make sure your PHP installation on Debian is capable of handling HTTP*S* requests. Make sure, OpenSSL is installed!

狼性发作 2024-12-14 23:39:59

这篇文章帮助我指明了正确的方向。要记住的一件事是
您的 PHP 安装可能不共享系统的 cURL / libcurl 设置。

http://blog.ianty.com/ubuntu/交换网络服务-ews-ntlmv2-and-linux/

This article helped point me in the right direction. One thing to keep in mind is that
your PHP installation may not be sharing your system's cURL / libcurl setup.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文