在继续之前要明确一点:不幸的是,这里不能选择使用 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 客户端代码会立即返回错误消息。