使用NTLM授权调用webservice

时间:2013-10-23 12:17:45

标签: php web-services ntlm dynamics-ax-2009 ax

我们需要使用NTLM授权在PHP中调用web服务,如果我理解正确,我们需要使用类似NTLMSoapClient的东西,但我不知道如何正确地调用它。

这是WSDL

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:tns="http://schemas.microsoft.com/dynamics/2008/01/services" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" name="CustomerService" targetNamespace="http://schemas.microsoft.com/dynamics/2008/01/services">
<wsp:Policy wsu:Id="BasicHttpBinding_CustomerService_policy">
<wsp:ExactlyOne>
<wsp:All>
<http:NegotiateAuthentication xmlns:http="http://schemas.microsoft.com/ws/06/2004/policy/http"/>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsdl:types>
<xsd:schema targetNamespace="http://schemas.microsoft.com/dynamics/2008/01/services/Imports">
<xsd:import schemaLocation="http://axwebsrv.igepabenelux.com/MicrosoftDynamicsAXAif50TST/customerservice.svc?xsd=xsd0" namespace="http://schemas.microsoft.com/dynamics/2008/01/services"/>
<xsd:import schemaLocation="http://axwebsrv.igepabenelux.com/MicrosoftDynamicsAXAif50TST/customerservice.svc?xsd=xsd6" namespace="http://schemas.microsoft.com/dynamics/2008/01/documents/Fault"/>
<xsd:import schemaLocation="http://axwebsrv.igepabenelux.com/MicrosoftDynamicsAXAif50TST/customerservice.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
<xsd:import schemaLocation="http://axwebsrv.igepabenelux.com/MicrosoftDynamicsAXAif50TST/customerservice.svc?xsd=xsd2" namespace="http://schemas.microsoft.com/dynamics/2006/02/documents/EntityKeyList"/>
<xsd:import schemaLocation="http://axwebsrv.igepabenelux.com/MicrosoftDynamicsAXAif50TST/customerservice.svc?xsd=xsd3" namespace="http://schemas.microsoft.com/dynamics/2006/02/documents/EntityKey"/>
<xsd:import schemaLocation="http://axwebsrv.igepabenelux.com/MicrosoftDynamicsAXAif50TST/customerservice.svc?xsd=xsd4"/>
<xsd:import schemaLocation="http://axwebsrv.igepabenelux.com/MicrosoftDynamicsAXAif50TST/customerservice.svc?xsd=xsd5" namespace="http://schemas.microsoft.com/dynamics/2008/01/documents/Customer"/>
<xsd:import schemaLocation="http://axwebsrv.igepabenelux.com/MicrosoftDynamicsAXAif50TST/customerservice.svc?xsd=xsd7" namespace="http://schemas.microsoft.com/dynamics/2006/02/documents/QueryCriteria"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="CustomerServiceUpdateRequest">
<wsdl:part name="parameters" element="tns:CustomerServiceUpdateRequest"/>
</wsdl:message>
<wsdl:message name="CustomerService_update_OutputMessage"/>
<wsdl:message name="CustomerService_update_AifFaultFault_FaultMessage">
<wsdl:part xmlns:q1="http://schemas.microsoft.com/dynamics/2008/01/documents/Fault" name="detail" element="q1:AifFault"/>
</wsdl:message>
<wsdl:message name="CustomerServiceDeleteRequest">
<wsdl:part name="parameters" element="tns:CustomerServiceDeleteRequest"/>
</wsdl:message>
<wsdl:message name="CustomerService_delete_OutputMessage"/>
<wsdl:message name="CustomerService_delete_AifFaultFault_FaultMessage">
<wsdl:part xmlns:q2="http://schemas.microsoft.com/dynamics/2008/01/documents/Fault" name="detail" element="q2:AifFault"/>
</wsdl:message>
<wsdl:message name="CustomerServiceFindKeysRequest">
<wsdl:part name="parameters" element="tns:CustomerServiceFindKeysRequest"/>
</wsdl:message>
<wsdl:message name="CustomerServiceFindKeysResponse">
<wsdl:part name="parameters" element="tns:CustomerServiceFindKeysResponse"/>
</wsdl:message>
<wsdl:message name="CustomerService_findKeys_AifFaultFault_FaultMessage">
<wsdl:part xmlns:q3="http://schemas.microsoft.com/dynamics/2008/01/documents/Fault" name="detail" element="q3:AifFault"/>
</wsdl:message>
<wsdl:message name="CustomerServiceFindRequest">
<wsdl:part name="parameters" element="tns:CustomerServiceFindRequest"/>
</wsdl:message>
<wsdl:message name="CustomerServiceFindResponse">
<wsdl:part name="parameters" element="tns:CustomerServiceFindResponse"/>
</wsdl:message>
<wsdl:message name="CustomerService_find_AifFaultFault_FaultMessage">
<wsdl:part xmlns:q4="http://schemas.microsoft.com/dynamics/2008/01/documents/Fault" name="detail" element="q4:AifFault"/>
</wsdl:message>
<wsdl:message name="CustomerServiceReadRequest">
<wsdl:part name="parameters" element="tns:CustomerServiceReadRequest"/>
</wsdl:message>
<wsdl:message name="CustomerServiceReadResponse">
<wsdl:part name="parameters" element="tns:CustomerServiceReadResponse"/>
</wsdl:message>
<wsdl:message name="CustomerService_read_AifFaultFault_FaultMessage">
<wsdl:part xmlns:q5="http://schemas.microsoft.com/dynamics/2008/01/documents/Fault" name="detail" element="q5:AifFault"/>
</wsdl:message>
<wsdl:message name="CustomerServiceCreateRequest">
<wsdl:part name="parameters" element="tns:CustomerServiceCreateRequest"/>
</wsdl:message>
<wsdl:message name="CustomerServiceCreateResponse">
<wsdl:part name="parameters" element="tns:CustomerServiceCreateResponse"/>
</wsdl:message>
<wsdl:message name="CustomerService_create_AifFaultFault_FaultMessage">
<wsdl:part xmlns:q6="http://schemas.microsoft.com/dynamics/2008/01/documents/Fault" name="detail" element="q6:AifFault"/>
</wsdl:message>
<wsdl:portType name="CustomerService">
<wsdl:operation name="update">
<wsdl:input wsaw:Action="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/update" name="CustomerServiceUpdateRequest" message="tns:CustomerServiceUpdateRequest"/>
<wsdl:output wsaw:Action="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/updateResponse" message="tns:CustomerService_update_OutputMessage"/>
<wsdl:fault wsaw:Action="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/updateAifFaultFault" name="AifFaultFault" message="tns:CustomerService_update_AifFaultFault_FaultMessage"/>
</wsdl:operation>
<wsdl:operation name="delete">
<wsdl:input wsaw:Action="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/delete" name="CustomerServiceDeleteRequest" message="tns:CustomerServiceDeleteRequest"/>
<wsdl:output wsaw:Action="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/deleteResponse" message="tns:CustomerService_delete_OutputMessage"/>
<wsdl:fault wsaw:Action="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/deleteAifFaultFault" name="AifFaultFault" message="tns:CustomerService_delete_AifFaultFault_FaultMessage"/>
</wsdl:operation>
<wsdl:operation name="findKeys">
<wsdl:input wsaw:Action="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/findKeys" name="CustomerServiceFindKeysRequest" message="tns:CustomerServiceFindKeysRequest"/>
<wsdl:output wsaw:Action="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/findKeysResponse" name="CustomerServiceFindKeysResponse" message="tns:CustomerServiceFindKeysResponse"/>
<wsdl:fault wsaw:Action="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/findKeysAifFaultFault" name="AifFaultFault" message="tns:CustomerService_findKeys_AifFaultFault_FaultMessage"/>
</wsdl:operation>
<wsdl:operation name="find">
<wsdl:input wsaw:Action="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/find" name="CustomerServiceFindRequest" message="tns:CustomerServiceFindRequest"/>
<wsdl:output wsaw:Action="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/findResponse" name="CustomerServiceFindResponse" message="tns:CustomerServiceFindResponse"/>
<wsdl:fault wsaw:Action="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/findAifFaultFault" name="AifFaultFault" message="tns:CustomerService_find_AifFaultFault_FaultMessage"/>
</wsdl:operation>
<wsdl:operation name="read">
<wsdl:input wsaw:Action="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/read" name="CustomerServiceReadRequest" message="tns:CustomerServiceReadRequest"/>
<wsdl:output wsaw:Action="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/readResponse" name="CustomerServiceReadResponse" message="tns:CustomerServiceReadResponse"/>
<wsdl:fault wsaw:Action="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/readAifFaultFault" name="AifFaultFault" message="tns:CustomerService_read_AifFaultFault_FaultMessage"/>
</wsdl:operation>
<wsdl:operation name="create">
<wsdl:input wsaw:Action="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/create" name="CustomerServiceCreateRequest" message="tns:CustomerServiceCreateRequest"/>
<wsdl:output wsaw:Action="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/createResponse" name="CustomerServiceCreateResponse" message="tns:CustomerServiceCreateResponse"/>
<wsdl:fault wsaw:Action="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/createAifFaultFault" name="AifFaultFault" message="tns:CustomerService_create_AifFaultFault_FaultMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="BasicHttpBinding_CustomerService" type="tns:CustomerService">
<wsp:PolicyReference URI="#BasicHttpBinding_CustomerService_policy"/>
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="update">
<soap:operation soapAction="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/update" style="document"/>
<wsdl:input name="CustomerServiceUpdateRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="AifFaultFault">
<soap:fault name="AifFaultFault" use="literal"/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="delete">
<soap:operation soapAction="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/delete" style="document"/>
<wsdl:input name="CustomerServiceDeleteRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="AifFaultFault">
<soap:fault name="AifFaultFault" use="literal"/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="findKeys">
<soap:operation soapAction="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/findKeys" style="document"/>
<wsdl:input name="CustomerServiceFindKeysRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="CustomerServiceFindKeysResponse">
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="AifFaultFault">
<soap:fault name="AifFaultFault" use="literal"/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="find">
<soap:operation soapAction="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/find" style="document"/>
<wsdl:input name="CustomerServiceFindRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="CustomerServiceFindResponse">
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="AifFaultFault">
<soap:fault name="AifFaultFault" use="literal"/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="read">
<soap:operation soapAction="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/read" style="document"/>
<wsdl:input name="CustomerServiceReadRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="CustomerServiceReadResponse">
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="AifFaultFault">
<soap:fault name="AifFaultFault" use="literal"/>
</wsdl:fault>
</wsdl:operation>
<wsdl:operation name="create">
<soap:operation soapAction="http://schemas.microsoft.com/dynamics/2008/01/services/CustomerService/create" style="document"/>
<wsdl:input name="CustomerServiceCreateRequest">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="CustomerServiceCreateResponse">
<soap:body use="literal"/>
</wsdl:output>
<wsdl:fault name="AifFaultFault">
<soap:fault name="AifFaultFault" use="literal"/>
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="CustomerService">
<wsdl:port name="BasicHttpBinding_CustomerService" binding="tns:BasicHttpBinding_CustomerService">
<soap:address location="http://axwebsrv.igepabenelux.com/MicrosoftDynamicsAXAif50TST/customerservice.svc"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

这是我使用SoapUI工作的请求:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://schemas.microsoft.com/dynamics/2008/01/services" xmlns:quer="http://schemas.microsoft.com/dynamics/2006/02/documents/QueryCriteria">
   <soapenv:Header/>
   <soapenv:Body>
      <ser:CustomerServiceFindRequest>
         <!--Optional:-->
         <quer:QueryCriteria>
            <quer:CriteriaElement>
               <quer:DataSourceName>CustTable    </quer:DataSourceName>
               <quer:FieldName>AccountNum    </quer:FieldName>
               <quer:Operator>Equal    </quer:Operator>
               <quer:Value1>99C00001    </quer:Value1>
               <!--Optional:-->
               <quer:Value2>?    </quer:Value2>
            </quer:CriteriaElement>
         </quer:QueryCriteria>
      </ser:CustomerServiceFindRequest>
   </soapenv:Body>
</soapenv:Envelope>

有人可以帮助处理需要编写的代码吗?

2 个答案:

答案 0 :(得分:0)

您是否尝试在AX中添加带有WSDL的Web引用?它不起作用吗? 选项是: 在AX中添加Web服务引用并开始使用API​​。 要么 在C#中编写类库,使用辅助方法引用Web服务并在AX中引用DLL。

答案 1 :(得分:0)

我们终于找到了解决问题的方法,从此页面获取代码:

http://blogs.msdn.com/b/freddyk/archive/2010/01/19/connecting-to-nav-web-services-from-php.aspx

这是我们正在使用的代码:

define('USERPWD', 'domain\\user:password');

// we unregister the current HTTP wrapper 
stream_wrapper_unregister('http'); 
// we register the new HTTP wrapper 
stream_wrapper_register('http', 'NTLMStream') or die("Failed to register protocol");

// Initialize Soap Client 
$client = new NTLMSoapClient('http://AXwebserver/MicrosoftDynamicsAXAif50TST/customerservice.svc?wsdl');

$accountNum = getVariable('accountNum', '$_GET');

$data= array('QueryCriteria' => 
          array('CriteriaElement' =>
               array('DataSourceName' => 'CustTable',
                     'FieldName'      => 'AccountNum',
                     'Operator'       => 'Equal',
                     'Value1'         => $accountNum
                    )
               )
          );


$result = $client->find($data); 

$result = $result->Customer->CustTable->Name;

echo 'Naam = ' . $result;

使用这两个类:

<?php
/* 
* Copyright (c) 2008 Invest-In-France Agency http://www.invest-in-france.org 
* 
* Author : Thomas Rabaix 
* 
* Permission to use, copy, modify, and distribute this software for any 
* purpose with or without fee is hereby granted, provided that the above 
* copyright notice and this permission notice appear in all copies. 
* 
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
*/

class NTLMSoapClient extends SoapClient { 
    function __doRequest($request, $location, $action, $version) { 
        $headers = array( 
            'Method: POST', 
            'Connection: Keep-Alive', 
            'User-Agent: PHP-SOAP-CURL', 
            'Content-Type: text/xml; charset=utf-8', 
            'SOAPAction: "'.$action.'"', 
        ); 
        $this->__last_request_headers = $headers; 
        $ch = curl_init($location); 
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 
        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_HTTPAUTH, CURLAUTH_NTLM); 
        curl_setopt($ch, CURLOPT_USERPWD, USERPWD); 
        $response = curl_exec($ch); 
        return $response; 
    }

    function __getLastRequestHeaders() { 
        return implode("\n", $this->__last_request_headers)."\n"; 
    } 
}

<?php

class NTLMStream 
{ 
    private $path; 
    private $mode; 
    private $options; 
    private $opened_path; 
    private $buffer; 
    private $pos; 
    /** 
     * Open the stream 
      * 
     * @param unknown_type $path 
     * @param unknown_type $mode 
     * @param unknown_type $options 
     * @param unknown_type $opened_path 
     * @return unknown 
     */ 
    public function stream_open($path, $mode, $options, $opened_path) { 
        $this->path = $path; 
        $this->mode = $mode; 
        $this->options = $options; 
        $this->opened_path = $opened_path; 
        $this->createBuffer($path); 
        return true; 
    } 
    /** 
     * Close the stream 
     * 
     */ 
    public function stream_close() { 
        curl_close($this->ch); 
    } 
    /** 
     * Read the stream 
     * 
     * @param int $count number of bytes to read 
     * @return content from pos to count 
     */ 
    public function stream_read($count) { 
        if(strlen($this->buffer) == 0) { 
            return false; 
        } 
        $read = substr($this->buffer,$this->pos, $count); 
        $this->pos += $count; 
        return $read; 
    } 
    /** 
     * write the stream 
     * 
     * @param int $count number of bytes to read 
     * @return content from pos to count 
     */ 
    public function stream_write($data) { 
        if(strlen($this->buffer) == 0) { 
            return false; 
        } 
        return true; 
    } 
    /** 
     * 
     * @return true if eof else false 
     */ 
    public function stream_eof() { 
        return ($this->pos > strlen($this->buffer)); 
    } 
    /** 
     * @return int the position of the current read pointer 
     */ 
    public function stream_tell() { 
        return $this->pos; 
    } 
    /** 
     * Flush stream data 
     */ 
    public function stream_flush() { 
        $this->buffer = null; 
        $this->pos = null; 
    } 
    /** 
     * Stat the file, return only the size of the buffer 
     * 
     * @return array stat information 
     */ 
    public function stream_stat() { 
        $this->createBuffer($this->path); 
        $stat = array( 
            'size' => strlen($this->buffer), 
        ); 
        return $stat; 
    } 
    /** 
     * Stat the url, return only the size of the buffer 
     * 
     * @return array stat information 
     */ 
    public function url_stat($path, $flags) { 
        $this->createBuffer($path); 
        $stat = array( 
            'size' => strlen($this->buffer), 
        ); 
        return $stat; 
    } 
    /** 
     * Create the buffer by requesting the url through cURL 
     * 
     * @param unknown_type $path 
     */ 
    private function createBuffer($path) { 
        if($this->buffer) { 
            return; 
        } 
        $this->ch = curl_init($path); 
        curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); 
        curl_setopt($this->ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); 
        curl_setopt($this->ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM); 
        curl_setopt($this->ch, CURLOPT_USERPWD, USERPWD); 
        $this->buffer = curl_exec($this->ch); 
        $this->pos = 0; 
    } 
}

?>