Accessing a WSDL with NTLM over SSL on IIS

  • BrendonKoz

    BrendonKoz - 2010-10-19

    I'm having problems with the ability to access a WSDL file on an IIS server (Exchange 2010 EWS API) that uses NTLM authentication over an SSL connection.

    When I strictly used cURL by itself to access the WSDL file, the handshake process alone took approximately 1.031 seconds. When trying to use NuSOAP to access the WSDL file *and* call a method, it is returning an error within 0.06 seconds. The other issue I'm having is that the debug string seems to be cleared when I run the call() method, and since no information is found, the debug string is empty (prior to the call it has data). Is this expected behavior?

    A pastebin to the WSDL file can be found here:
    The example cURL code is shown below:

        $c = curl_init();
        curl_setopt($c, CURLOPT_URL, '');
        curl_setopt($c, CURLOPT_FAILONERROR, true); 
        curl_setopt($c, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($c, CURLOPT_USERPWD, "");
        curl_setopt($c, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
        $page = curl_exec($c);
        echo '<pre>'.htmlspecialchars($page).'</pre>';

    My NuSOAP code, which is attempting to mimic the cURL script is below (with various commented out code and attempts made - all with the same results):

        $username = '';
        $password = 'password';
        $ews_url  = '';
        $soapclient = new nusoap_client($service, true);
        $err = $soapclient->getError();
            die('Error: '.$err);
        $soapclient->setCredentials($username, $password, 'ntlm');
    #    $soapclient->setCredentials('', '', 'ntlm');
    #    $soapclient->setUseCurl(true);
    #    $soapclient->useHTTPPersistentConnection();
    #    $soapclient->setCurlOption(CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
    #    $soapclient->setCurlOption(CURLOPT_SSL_VERIFYPEER, 0);
    #    $soapclient->setCurlOption(CURLOPT_RETURNTRANSFER, 1);
    #    $soapclient->setCurlOption(CURLOPT_USERPWD, $username.':'.$password);
        $soapclient->soap_defencoding = 'UTF-8';
        $proxy = $soapclient->getProxy();
        echo '<pre>'; echo htmlspecialchars($soapclient->debug_str, ENT_QUOTES); echo '</pre>';
            die('Error: '.$err);
        $xml  = '<FindItem xmlns="" xmlns:t="" Traversal="Shallow"><ItemShape><t:BaseShape>IdOnly</t:BaseShape><t:AdditionalProperties><t:FieldURI FieldURI="message:From"/><t:FieldURI FieldURI="item:Subject"/><t:FieldURI FieldURI="message:IsRead"/><t:FieldURI FieldURI="item:DateTimeReceived"/><t:FieldURI FieldURI="calendar:Start"/><t:FieldURI FieldURI="calendar:End"/><t:FieldURI FieldURI="calendar:Location"/><t:FieldURI FieldURI="task:Status"/><t:FieldURI FieldURI="task:DueDate"/></t:AdditionalProperties></ItemShape><IndexedPageItemView Offset="0" MaxEntriesReturned="5" BasePoint="Beginning"/><ParentFolderIds><t:DistinguishedFolderId Id="inbox"/></ParentFolderIds></FindItem>';
        $operation = 'FindItem';
        $result = $soapclient->call($operation, $xml);
        echo '<pre>'; print_r($result); echo '</pre>';
            echo 'FAULT: ';
            echo '<pre>'; print_r($result); echo '</pre>';
            $err = $soapclient->getError();
            if ($err) {
                echo '<p><b><u>Error</u>:</b><br />' . $err . '</p>';
                echo 'Connection succeeded.';

    The error message given is: "operation FindItem not present in WSDL."
    Prior to that error message, I was receiving the message of "no operations defined in the WSDL document!".
    …I believe this to be NTLM/SSL related.

    The debug string contains the following information:

    2010-10-19 16:09:06.799285 nusoap_client: ctor wsdl=1 timeout=0 response_timeout=30
    2010-10-19 16:09:06.799404 nusoap_client: will use lazy evaluation of wsdl from
    2010-10-19 16:09:06.799464 nusoap_client: setCredentials authtype=ntlm certRequest=
    array(0) {
    2010-10-19 16:09:06.799531 nusoap_client: in getProxy endpointType=wsdl
    2010-10-19 16:09:06.799592 nusoap_client: instantiating wsdl class with doc:
    2010-10-19 16:09:06.799677 wsdl: ctor wsdl= timeout=0 response_timeout=30
    2010-10-19 16:09:06.799735 wsdl: parse and process WSDL path=
    2010-10-19 16:09:06.799802 wsdl: setCredentials authtype=ntlm certRequest=
    array(0) {
    2010-10-19 16:09:06.799865 wsdl: parse and process WSDL path=
    2010-10-19 16:09:06.799929 nusoap_client: checkWSDL
    2010-10-19 16:09:06.799985 wsdl: getOperations for port '' bindingType
    2010-10-19 16:09:06.800037 wsdl: getOperations found no operations for port '' bindingType
    2010-10-19 16:09:06.800091 wsdl: getOperations for port '' bindingType
    2010-10-19 16:09:06.800142 wsdl: getOperations found no operations for port '' bindingType
    2010-10-19 16:09:06.800197 nusoap_client: getOperations returned false
    2010-10-19 16:09:06.800254 nusoap_client: Error from _getProxyClassCode, so return NULL

    From what I can tell, no where in the debug does it establish a connection with the WSDL file. Does anyone have any ideas as to what I could try next? The location of the WSDL file is correct with 0 redirects (cURL helped me to verify this).

    Thank you.

  • BrendonKoz

    BrendonKoz - 2010-10-22

    I've solved this problem. It seems to be a problem with the Services.wsdl file's formatting…among stupid, overlooked mistakes in my own code. My solution has been posted at StackOverflow, but I'll post the example working code here as well.

        $username = '';
        $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=""';
        $xml .= ' xmlns:t="" 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>';

    The solution was missed while reading/skimming over other solutions. An additional section needed to be added to the WSDL file to let languages other than .NET know where to look for further information. (In this instance, changing the types.xsd was not necessary and actually broke the script.) Solution from a Java (bedework) Wiki:

  • Scott Nichol

    Scott Nichol - 2011-01-13

    Thank you for posting your solution here.


Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

No, thanks