user1825814
user1825814

Reputation: 51

php soap server ignores header in wsdl mode

I have a SOAP server web service and a SOAP client on another server to test my web service.

In wsdl-mode the SOAP server ignores the header and header function, thus ignoring the client authentication details. Meaning the client doesn't authenticate. The SOAP server is on a https domain.

The SOAP server and client works perfectly in non-wsdl mode.

Can anybody please tell me what I am doing wrong?

Here is my SOAP client:

    $params = 'LHAFDS89';

    ini_set('soap.wsdl_cache_enabled',0);
    ini_set('soap.wsdl_cache',0);
    ini_set('soap.wsdl_cache_ttl',0);

    $client = new SoapClient('https://www.example.com/webservices/example.wsdl', array('trace'=>true));

    $authentication['key'] = "n/KLASDF9ASDF9832JDAFJ234=";

    $auth_key = $authentication['key'];
    $auth_mode = 't';

    $auth = new SOAPAuth($auth_key,$auth_mode);

    $header[] = new SoapHeader("urn:www.example.com",'authenticateClient',$auth,0);
    $client->__setSoapHeaders($header);

    try
    {
        $result = $client->soapFunction($params);
    }
    catch (SoapFault $e) 
    {
        echo "<script>alert('".$e->faultcode.'\n\n'.$e->faultstring."');</script>";
    }

    echo $result['message'];

class SOAPAuth 
{
    public $key;
    public $mode;

public function __construct($key, $mode) 
    {
      $this->key = $key;
      $this->mode = $mode;
    }
}

SOAP Server:

class ExampleClass {

    protected $user_is_valid;
    protected $mode;

    public function __construct()
    {
        $this->user_is_valid = false;
        $this->mode = '';
    }

    public function authenticateClient($header){
        if (isset($header->key) && isset($header->mode)){
            $authentication['key'] = $header->key;
            $this->mode = $header->mode;
            if($authentication['key']== 'n/KLASDF9ASDF9832JDAFJ234=')
            {
                $this->user_is_valid = true;
            }
        }
    } 

    public function soapFunction($params)
    {
        if($this->user_is_valid == true){

                $result['message'] = "User is valid."
                return $result; 

        } else {
            throw new SoapFault("Authorization:", "Failed!"); 
        }
    }
}

ini_set('soap.wsdl_cache_enabled',0);
ini_set('soap.wsdl_cache',0);
ini_set('soap.wsdl_cache_ttl',0);

$example_class = new ExampleClass();
$server = new SoapServer("example.wsdl");

$server->setObject($example_class);
$server->handle();    

WSDL:

<?xml version="1.0" encoding="utf-8"?>

<definitions name="Example"
   targetNamespace="urn:Example"
   xmlns:typens="urn:Example"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
   xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
   xmlns="http://schemas.xmlsoap.org/wsdl/">

   <message name='header'>
     <part name='key' type='xsd:string'/>
     <part name='mode' type='xsd:string'/>
   </message>

   <message name='soapFunction_request'>
     <part name='params' type='xsd:string'/>
   </message>       
   <message name='soapFunction_response'>
     <part name='result' type='xsd:string[]'/>
   </message>

   <portType name='soapFunctionPortType'>
     <operation name='soapFunction'>
       <input message='tns:soapFunction_request'/>
       <output message='tns:soapFunction_response'/>
     </operation>
    </portType>

    <binding name='soapFunctionBinding' type='tns:soapFunctionPortType'>
    <soap:binding style='rpc'
         transport='http://schemas.xmlsoap.org/soap/http'/>
     <operation name='soapFunction'>
     <soap:operation soapAction='urn:soapFunction'/>
     <input>
        <soap:header message="header" part="key"/>
        <soap:header message="header" part="mode"/>
        <soap:body use='encoded' namespace='urn:soapFunction'
            encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
     </input>
     <output>
        <soap:body use='encoded' namespace='urn:soapFunction'
            encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'/>
     </output>
     </operation>
      </binding>

      <service name='soapFunctionService'>
     <port name='soapFunctionServicePort' binding='soapFunctionBinding'>
      <soap:address location='https://www.example.com/webservices/soapServer.php'/>
     </port>
      </service>
</definitions> 

Any help would be appreciated.

Upvotes: 2

Views: 2816

Answers (1)

user1825814
user1825814

Reputation: 51

I found a solution to my problem. It is not exactly what I had in mind, but it works.

I let the SOAP clients connect to my SOAP server in wsdl mode and I let the SOAP server respond in non wsdl mode.

For some reason the headers do not get ignored while working this way, the client authenticates correctly and the client's input get checked against the wsdl for validity.

Upvotes: 1

Related Questions