2010-10-18 110 views
2

在继续之前要清楚:使用PHP的内置SOAP类不幸的是这里不是一个选项(生产服务器的PHP不是用它构建的,也不是)。帮助Exchange 2010 EWS(API)和/或PHP的NuSOAP库?


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

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

我已经尝试过各种各样的代码示例,不幸的是我不熟悉XML,SOAP或cURL(这几乎是所有在这里使用的技术)。我的代码当前迭代如下发现:

<?php 

include_once('./lib/nusoap.php'); 

$username = '[email protected]'; 
$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(...)),代码将输出“Connection succeeded。”,但它会在有或者没有尝试的NTLM认证码的情况下执行此操作。

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

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

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

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

+0

我在SourceForge上的NuSOAP“forum”上创建了一个主题,希望snichols能够看到它并能够提供帮助。它还包含更多信息。它可以在以下网址找到:https://sourceforge.net/projects/nusoap/forums/forum/193578/topic/3904487 – BrendonKoz 2010-10-19 20:19:56

+0

我现在已经在Exchange开发者论坛上开始了一个主题,并希望得到一些进一步的见解。 http://social.technet.microsoft.com/Forums/en-US/exchangesvrdevelopment/thread/6fe6224c-a4d6-45f9-a93a-847f297d4cbd – BrendonKoz 2010-10-20 21:44:43

回答

2

有几件事你会想在这里看看。

  1. 在调用实际的soap_client时出现错误。你在一个名为$ ews_url的变量中定义了端点,然后用$ service调用了构造函数。

  2. 为什么要向$ xml变量中的字符串中添加字符串 - 可能是在您想要连接的急忙中? (运营商:+ vs。)

  3. 使用以下针对在EWS中使用Java的维基信息,似乎微软再一次在他们的公共协议的实现中失败了。类型的修改。这个Wiki中的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 = '[email protected]'; 
    $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文件,并且所有可能都按预期工作,没有所有这些麻烦。不幸的是,我无法证实这一点。

+0

WSDL和XSD文件的本地版本必须可通过网络访问,否则NuSOAP将获得根据初始端点参数无法读取它们。例如,当试图在端点上使用相对路径时,这是错误消息:“到WSDL文件的错误路径://./messages.xsd”。要记住的事情。 – BrendonKoz 2010-10-25 16:34:51

+0

对libcurl或某些Windows服务/驱动程序的更新可能会导致此脚本的互操作性问题。如果你在linux服务器上运行类似的代码,你需要确保你的curl/libcurl版本支持NTLMv2(> = v7.25),显然还有SSL。 – BrendonKoz 2012-07-25 20:56:12