3

I am trying to setup a SOAP request in PHP using HTTP basic Authentication. For some reason I keep getting, HTTP/1.1 401 Unauthorized error.

This is an example of the request I'm trying to create:

POST https://url/someurl/soap HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "SomeSoapAction"
User-Agent: SomeUser Client-HttpClient/3.1
Content-Length: 1503
Authorization: Basic dGsomebasicreyteryheyp0ZXN0ZXI=
Host: somehost.com  

This is a snippet of my code:

ini_set('display_errors',1);
ini_set("soap.wsdl_cache_enabled", "0");
error_reporting(E_ALL);
$wsdl = "urltosomewsdlfile.wsdl";
$url = "somerl";
$username = "username";
$password = "password";
$encodedstuff = base64_encode("{$username}:{$password}");

$client = new SoapClient($wsdl, array('exceptions' => true,'trace' => true,'login' => 'somelogin', 'password' => 'somepw'));
$header = new SoapHeader($url, 'Authorization: Basic', $encodedstuff);
$client->__setSoapHeaders($header);

try {
    $result = $client->SomeSoapAction();
    } catch (SoapFault $soapFault) {
        var_dump($soapFault);
        echo "<br />Request :<br />", htmlentities($client->__getLastRequest()), "<br />";
        echo "<br />Response :<br />", htmlentities($client->__getLastResponse()), "<br />";
    }

If I take the username and password out of the new SoapClient section it throws up Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from...

If I put in the base64 encoded variable to the new SoapClient section instead of the username/pw it throws the same Parsing error as above: $client = new SoapClient($wsdl, array( 'authentication' => "Basic $encodedstuff", 'exceptions' => true,'trace' => true,));

The username and password work when loading the URL directly.

Can anyone point me in the right direction? Thanks for any help.


Update 12/18/18: I've been trying this as a new method suggested, but still receive the same 401 error message:

$opts = array( 'http'=>array( 'method'=>"POST", 'header' => "Authorization: Basic " . base64_encode("{$user}:{$pw}") ) ); 
$context = stream_context_create($opts); 
$client = new SoapClient($wsdl, array('stream_context' => $context,'exceptions' => true,'trace' => true,)); 
$header = new SoapHeader($url, 'Authorization: Basic', $encodedstuff); 
$client->__setSoapHeaders($header);

Update 15/01/19: I'm still having issues with this.

Using SOAPUI I can make a successful request and gain authentication. I can't see what the difference is between the SOAPUI request and my own PHP request.

I've noticed that the request header created by my PHP code alters the POST and Host endpoint URLs. The first part of the POST URL has the domain removed and the Host also has the first section of the URL removed.

SOAPUI request header (correct returns 200):

POST https://test-example.com/file/SOAP HTTP/1.1
Host: test-example.com

PHP request header (returns a 401):

POST /file/SOAP HTTP/1.1
Host: example.com

This seems to be causing the problem as it looks as if I'm pointing to the wrong endpoint. Does anyone have any advice on what might be wrong with my PHP code to break this request? Thanks.

T W
  • 439
  • 1
  • 6
  • 15
  • When using HTTP basic authentication, the SoapClient will only send the credentials when invoking the service, not when fetching the WSDL. Is the WSDL protected with Basic Auth? – odan Dec 12 '18 at 09:24
  • Yes, the .wsdl file requires a login&pw to access. – T W Dec 12 '18 at 14:53
  • Since 5.2.9, SoapClient no longer attempts HTTP Basic authentication to retrieve a wsdl file. [Read more](https://bugs.php.net/bug.php?id=47761) – odan Dec 12 '18 at 15:51
  • Would that be why I get a 401 - because the soap client isn't trying to authenticate when it gets the file, but the remote server expects basic authentication? One other question, in your opinion should the code above work in theory? Thanks for your help. – T W Dec 12 '18 at 16:41
  • Yes probably, because 401 means "Unauthorized". The line `$header = new SoapHeader($url, 'Authorization: Basic'` makes no sense to me because Basic Auth is a HTTP-Header and not part of the HTTP payload (content). – odan Dec 12 '18 at 17:32
  • Thanks for your help. I'm still working on it but as yet haven't made it connect. Will update on here if I find a solution. – T W Dec 14 '18 at 17:44
  • You should [create a context to do the authentication](https://stackoverflow.com/a/30630753/1255289) and then pass it as `stream_context` option in `new SoapClient`. – miken32 Dec 18 '18 at 18:39
  • Hi @miken32 thanks for your comment. I've given this a go - code updated above to reflect what I tried, but I still receive the same 401 message. Thanks for your help. – T W Dec 18 '18 at 20:42
  • And you've confirmed that both `$user` and `$pw` contain valid data in that context? – miken32 Dec 18 '18 at 20:44
  • They work to log into the wsdl file directly through a browser. Thanks. – T W Dec 18 '18 at 20:46

0 Answers0