【问题标题】:Help with Exchange 2010 EWS (API) and/or PHP's NuSOAP library?有关 Exchange 2010 EWS (API) 和/或 PHP 的 NuSOAP 库的帮助?
【发布时间】:2011-04-27 02:53:06
【问题描述】:

在继续之前要明确一点:很遗憾,这里不能选择使用 PHP 的内置 SOAP 类(生产服务器的 PHP 不是用它构建的,也不会使用它)。


我正在尝试使用 EWS 来对完全外部服务器应用程序的用户进行身份验证。 LDAP 身份验证已被禁止。我已通过 Microsoft 自动发现工具 http://www.testexchangeconnectivity.com/ 验证了我的 EWS wsdl 是否正确。 WSDL 的内容可以在这里找到:http://pastebin.org/214070

服务器正在使用 SSL,并且正在使用“NTLM”的 EWS 的默认身份验证方法。

我尝试了网络上的各种代码示例,遗憾的是我并不精通 XML、SOAP 或 cURL(这几乎是这里使用的所有技术)。我的代码的当前迭代如下:

<?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 '</pre>';

if($soapclient->fault){
    echo 'FAULT: ';
    echo '<pre>'; print_r($result); echo '</pre>';
}else{
    $err = $soapclient->getError();
    if ($err) {
        echo '<p><b><u>Error</u>:</b><br />' . $err . '</p>';
    }else{
        echo 'Connection succeeded.';
    }
}
?>

我遇到的实际问题是 NuSOAP 返回一般错误消息:“没有在 WSDL 文档中定义的操作!”。从 WSDL 的外观来看,这似乎不正确,让我相信我在代码中遗漏了一些东西。如果我删除代码中的实际客户端调用 ($soapclient->call(...)),代码会打印出“连接成功。”,但无论是否尝试 NTLM 身份验证代码,它都会执行此操作。

我也尝试在我的开发机器上使用“php-ews”项目(即使相同的代码在生产服务器上不起作用)并且也无法在没有收到错误的情况下访问任何内容。

如果有人对这些技术有任何经验并且可能能够指出一些澄清(或可能的错误),我将不胜感激。如果我需要进一步澄清,请告诉我。

更新 1: 加载 WSDL 的一个错误似乎是 NTLM 身份验证。单独使用 cURL(没有 NuSOAP)我能够访问 WSDL 文件并发现服务器正在重定向到不同的端点位置(.../EWS/Services.wsdl)。

不幸的是,我尝试使用 NuSOAP 库的 cURL 功能并通过 NuSOAP 设置相同的选项,但我仍然收到相同的通用错误消息,就好像 NuSOAP 只是无法查看/查看/访问 WSDL 文件一样。我相信它可能仍然是 NTLM 身份验证,因为 cURL 版本需要一些时间才能返回(NTLM 它是一个多步骤握手过程),而 NuSOAP 客户端代码会立即返回错误消息。

【问题讨论】:

标签: php exchange-server ntlm nusoap exchangewebservices


【解决方案1】:

您需要在此处查看一些内容。

  1. 调用实际的soap_client 时出错。您在名为 $ews_url 的变量中定义了端点,但随后使用 $service 调用了构造函数。

  2. 您为什么要在 $xml 变量中的字符串中添加一个字符串 - 也许您急于要连接? (运算符:+ 与 .)

  3. 使用以下指向在 Java 中使用 EWS 的 Wiki 信息,似乎 Microsoft 在实现通用协议时再次犯了错误。此 Wiki 中对 types.xsd 的修改实际上会导致问题,因此请忽略该更改,但下载 Services.wsdl 的本地副本并将其修改为指向您自己的服务器似乎可以正常工作。 http://www.bedework.org/trac/bedework/wiki/ExchangeWSlink text

只要您下载了您的 types.xsd、messages.xsd 和 Services.wsdl 的本地副本并修改了 Services.wsdl 文件以添加与您的服务器相关的所需信息,以下代码应该可以工作。确保这些文件的本地副本位于服务器上的同一文件夹中。

<?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 '</pre>';
?>

解决方案似乎都源于拥有主要 SOAP 参考文件的本地副本,并修复了 Services.wsdl 文件。如果您有权访问 Exchange 服务器,则可能能够修改 Services.wsdl 文件,并且一切都可以按预期工作,没有所有这些麻烦。很遗憾,我无法验证这一点。

【讨论】:

  • 本地版本的 WSDL 和 XSD 文件必须是 Web 可访问的,否则 NuSOAP 将无法根据初始端点参数读取它们。例如,当尝试在端点上使用相对路径时,这是错误消息:“WSDL 文件的错误路径://./messages.xsd”。需要记住的一点。
  • 对 libcurl 或某些 Windows 服务/驱动程序的更新可能会导致与此脚本的互操作性问题。如果您在 linux 服务器上运行类似的代码,您需要确保您的 curl/libcurl 版本支持 NTLMv2 (>=v7.25),当然还有 SSL。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多