java.lang.NullPointerException on PHP soap request - php

I am trying soap request with authentication. Wdsl server requiring user authentication. So i used SOAP header method.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.connector.uut.cs.com.tr/">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>my_user_name</wsse:Username>
<wsse:Password>my_password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<ser:sendInvoice>
<id>123456</id>
<type>INVOICE</type>
<invoiceNo>AAA123456001</invoiceNo>
<data></data>
<hash>dfa06b85d66ef786f9f091f38e09c184</hash>
<mimeType>application/xml</mimeType>
<version>1.0</version>
</ser:sendInvoice>
</soapenv:Body>
</soapenv:Envelope>
Php soap request:
$auth = array(
'Username' => 'my_user_name',
'Password' => 'my_password',
);
$url = 'https://test.com/ws/connectorService?wsdl';
try {
$request = new SoapClient( $url, $auth );
$header = new SOAPHeader( $url, 'Security', $auth );
$request->__setSoapHeaders( $header );
$result = $request->sendInvoice();
} catch( Exception $exc ) {
$result = $exc->getMessage();
}
The $result is printing "java.lang.NullPointerException".

Related

soap api able to connect in SoapUI but not in PHP

I've been failing to consume a soap webservice with soapClient /nusoap I believe the issue might be with my header but I'm not sure as the error I get back are pretty vague at times.
We've been able to get it to work in SoapUI, which adds some additional things to the header notably this:
<wsa:Action>http://www.property24.com/services/IP24ListingServiceWcf/FetchAgents</wsa:Action><wsa:To>https://www.exdev.property24.com/Services/P24ListingService46.svc</wsa:To>
Its being added in SoapUI automaticaly by checking: add default WSA:to under WS-A
inside the header it also has xmlns:wsa="http://www.w3.org/2005/08/addressing" I dont know how to correctly set this if possible.
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ser="http://www.property24.com/services">
<soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<ser:CredentialsHeader>
<!--Optional:-->
<ser:EMail>..</ser:EMail>
<!--Optional:-->
<ser:Password>..!</ser:Password>
<!--Optional:-->
<ser:UserGroupEmailId>1</ser:UserGroupEmailId>
</ser:CredentialsHeader>
<wsa:Action>http://www.property24.com/services/IP24ListingServiceWcf/FetchAgents</wsa:Action><wsa:To>https://www.exdev.property24.com/Services/P24ListingService46.svc</wsa:To></soap:Header>
<soap:Body>
<ser:FetchAgents>
<!--Optional:-->
<ser:agencyId>..</ser:agencyId>
</ser:FetchAgents>
</soap:Body>
</soap:Envelope>
I'm getting a bad request response which I believe could be due to the header
this is what I've tried:
$headerbody = array(
'EMail' => $username,
'Password' => $password,
'UserGroupEmailId'=> $groupId
);
$headers[] = new SoapHeader('https://www.exdev.property24.com/', 'wsa:Action', "http://www.property24.com/services/IP24ListingServiceWcf/$method");
$headers[] = new SoapHeader('https://www.exdev.property24.com/', 'wsa:To', "https://www.exdev.property24.com/Services/P24ListingService46.svc");
$headers[] = new SoapHeader('https://www.exdev.property24.com/', 'CredentialsHeader', $headerbody);
$client->__setSoapHeaders($headers);
and
$header_part = '<CredentialsHeader><EMail>....</EMail><Password>....</Password><UserGroupEmailId>1</UserGroupEmailId></CredentialsHeader>';
$header_part .= '<wsa:Action>http://www.property24.com/services/IP24ListingServiceWcf/$method</wsa:Action><wsa:To>https://www.exdev.property24.com/Services/P24ListingService46.svc</wsa:To>';
$soap_var_header = new SoapVar($header_part, XSD_ANYXML, null, null, null);
$soap_header = new SOAPHeader('http://www.w3.org/2005/08/addressing', 'wsa',
$soap_var_header);
$client->__setSoapHeaders($soap_header);
I've not had a lot of experience with Soap webservices and have been stuck on this for quite some time thanks guys
construct header object by concatenating with user credentials
$headerStr= '
<ser:CredentialsHeader>
<!--Optional:-->
<ser:EMail>'.$username.'</ser:EMail>
<!--Optional:-->
<ser:Password>'.$password.'</ser:Password>
<!--Optional:-->
<ser:UserGroupEmailId>'.$groupId.'</ser:UserGroupEmailId>
</ser:CredentialsHeader>
<wsa:Action>http://www.property24.com/services/IP24ListingServiceWcf/FetchAgents</wsa:Action><wsa:To>https://www.exdev.property24.com/Services/P24ListingService46.svc</wsa:To>
';
$header= new \SoapHeader('http://www.w3.org/2005/08/addressing',
'wsa',
new \SoapVar($headerStr, XSD_ANYXML),
true
);
then construct SoapClient and set headers and operation name with parameters
$soapclient = new SoapClient($serviceURL,$options);
$soapclient-> __setSoapHeaders($header);
parameters can be sent as dictionary but very important to chang "Request" to be identical to the same name in service contract
$param=array ("Request" => array('agencyId'=>'123'));
$response =$soapclient->FetchAgents( $param);
var_dump(json_encode($response));
echo '<br><br><br>';
$array = json_decode(json_encode($response), true);
print_r($array);
the complete code snippet will be
try {
$options = [
"soap_version" => SOAP_1_2, // SOAP_1_1
'trace' => 1,
'exception' => 1,
'keep_alive' => false,
'connection_timeout' => 500000
];
$headerStr = '
<ser:CredentialsHeader>
<!--Optional:-->
<ser:EMail>' . $username . '</ser:EMail>
<!--Optional:-->
<ser:Password>' . $password . '</ser:Password>
<!--Optional:-->
<ser:UserGroupEmailId>' . $groupId . '</ser:UserGroupEmailId>
</ser:CredentialsHeader>
<wsa:Action>http://www.property24.com/services/IP24ListingServiceWcf/FetchAgents</wsa:Action><wsa:To>https://www.exdev.property24.com/Services/P24ListingService46.svc</wsa:To></soap:Header>
';
$header = new \SoapHeader(
'http://www.w3.org/2005/08/addressing',
'ws',
new \SoapVar($headerStr, XSD_ANYXML),
true
);
$soapclient = new SoapClient($serviceURL, $options);
$soapclient->__setSoapHeaders($header);
$param = array('agencyId' => '123');
$response = $soapclient->FetchAgents($param);
// print the last XML request to compare with the working one in soapUI
echo "REQUEST:\n" . $soapclient->__getLastRequest() . "\n";
var_dump(json_encode($response));
echo '<br><br><br>';
$array = json_decode(json_encode($response), true);
print_r($array);
} catch (Exception $e) {
echo $e->getMessage();
}

Soap request working in SoapUI but not in Wordpress plugin

I've been searching around for a solution to my problem, but to no avail. I'm trying to send a soap request through a Wordpress plugin using the following:
function soapRequest($soapUsername, $soapNonce, $soapDateTime, $soapPassword) {
$wsdl = 'http://www.beautyfort.com/api/wsdl/v2/wsdl.wsdl';
$trace = true;
$exceptions = false;
$client = new SoapClient($wsdl, array('trace' => $trace, 'exceptions' => $exceptions));
// Must be a stdClass (and not an array)
$auth = new stdClass();
$auth->Username = $soapUsername;
$auth->Nonce = $soapNonce;
$auth->Created = $soapDateTime;
$auth->Password = $soapPassword;
$header = new SoapHeader('http://www.beautyfort.com/api/', 'AuthHeader', $auth);
$client->__setSoapHeaders($header);
$xml_array['TestMode'] = 'true';
$xml_array['StockFileFormat'] = 'JSON';
$xml_array['SortBy'] = 'StockCode';
try {
$response = $client->GetStockFile($xml_array);
}
catch (Exception $e) {
log_me("Error!");
log_me($e -> getMessage());
log_me('Last response: '. $client->__getLastResponse());
}
log_me('Last request: '. $client->__getLastRequest());
log_me($response);
}
This produces the following request:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://www.beautyfort.com/api/">
<SOAP-ENV:Header>
<ns1:AuthHeader>
<ns1:Username>joetest</ns1:Username>
<ns1:Nonce>htflFfIKM4</ns1:Nonce>
<ns1:Created>2019-02-09T10:13:51.000Z</ns1:Created>
<ns1:Password>NGFjYTJiNzJmOWY2MzBmY2M2MjJkNjg1MDgyMWRjMzQxOGY1YTNjYQ==</ns1:Password>
</ns1:AuthHeader>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:GetStockFileRequest>
<ns1:TestMode>true</ns1:TestMode>
<ns1:StockFileFormat>JSON</ns1:StockFileFormat>
<ns1:SortBy>StockCode</ns1:SortBy>
</ns1:GetStockFileRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
And I get an invalid credentials error. I've also been testing in SoupUI and the following request works:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:api="http://www.beautyfort.com/api/">
<soapenv:Header>
<api:AuthHeader>
<api:Username>joetest</api:Username>
<api:Nonce>tJrsRlQt6i</api:Nonce>
<api:Created>2019-02-06T23:34:11.000Z</api:Created>
<api:Password>ZTBhMmE5OGY4YTNlZWIzZTE0ZTc2ZjZiZDBhM2RhMjJmNzAxNzYwZA==</api:Password>
</api:AuthHeader>
</soapenv:Header>
<soapenv:Body>
<api:GetStockFileRequest>
<api:TestMode>true</api:TestMode>
<api:StockFileFormat>JSON</api:StockFileFormat>
<!--Optional:-->
<api:FieldDelimiter>,</api:FieldDelimiter>
<!--Optional:-->
<api:StockFileFields>
<!--1 or more repetitions:-->
<api:StockFileField>StockCode</api:StockFileField>
<api:StockFileField>Category</api:StockFileField>
<api:StockFileField>Brand</api:StockFileField>
<api:StockFileField>Collection</api:StockFileField>
<api:StockFileField>Category</api:StockFileField>
</api:StockFileFields>
<api:SortBy>StockCode</api:SortBy>
</api:GetStockFileRequest>
</soapenv:Body>
</soapenv:Envelope>
Now the only differences I can see (apart from the optional fields) is the names of the namespace, and the use of the Xml tag at the top of the request. Both of these shouldn't matter right? I'd really appreciate your help on this as I've been scratching my head for ages.
Thank you in advance!
Your perfect just need to set UTC timezone and secret format like below:
base64 encoded(sha1(Nonce . Created . Secret))

ns1:FailedAuthenticationThe security token could not be authenticated or authorized

here is my xml code for authentication:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:esf="esf">
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>my_username</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">my_password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<esf:createSessionRequest>
<tin>my_bin</tin>
<x509Certificate>my_cert</x509Certificate>
</esf:createSessionRequest>
</soapenv:Body>
</soapenv:Envelope>
there is connection to site
try{ $CreateSession = $SessionService>__doRequest
($Create_session_xml, 'https://esf.gov.kz:8443/esfweb/ws/SessionService wsdl', '', SOAP_1_2);
echo $CreateSession;// here I get error: FailedAuthenticationThe security token could not be authenticated or authorized
} catch(SoapFault $e){
echo "Error: ".$e->getMessage().PHP_EOL;
}
I registered on this site, checked it. So problems with my datas no.
is there any idea? please help, I searched through internet, no results.
Edit: Initialization of the soap client taken from the comments.
$SessionService = new SoapClient(NULL, [
"location" => "esf.gov.kz:8443/esf-web/ws/SessionService",
"uri" => "esf-test.kgd.gov.kz:9443",
"style" => SOAP_DOCUMENT,
"use" => SOAP_LITERAL,
"stream_context" => $context
]);

Interacting with a soap API without WSDL in PHP

Recently got access to a soap API for a hotel management service. They have provided documentation which shows a basic example of a request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<Auth xmlns="http://xxxx/xxxxAPI">
<FromSystemId ID="1">CompanyName</FromSystemId>
<UserName>username</UserName>
<Password>password</Password>
</Auth>
</soapenv:Header>
<soapenv:Body>
<GetRegions Timestamp="2016-04-11" Version="1.0" Lang="en"
xmlns="http://xxxx/xxxxAPI">
<Country Code="GB" />
</GetRegions>
</soapenv:Body>
</soapenv:Envelope>
They have also provided a list of functions in their documentation and the parameters required for each of the functions. But i am abit confused on how to perform a request as i have never used a soap API before. They also haven't provided a WSDL, does this matter?
Anyway, here is how i thought to try and perform a request
$soapURL = "http://xxxx/xxxxAPI" ;
$soapParameters = Array('login' => "username", 'password' => "password") ;
$soapFunction = "getRegions";
$soapFunctionParameters = Array('countrycode' => 'GB');
$soapClient = new SoapClient($soapURL, $soapParameters);
$soapResult = $soapClient->__soapCall($soapFunction,
$soapFunctionParameters) ;
if(is_array($soapResult) && isset($soapResult['someFunctionResult'])) {
// Process result.
} else {
// Unexpected result
if(function_exists("debug_message")) {
debug_message("Unexpected soapResult for {$soapFunction}: ".print_r($soapResult, TRUE)) ;
}
}
Am i going about this the right way? i am unable to test this right now as i haven't received my authentication but wanted to make a start on it now.
Any help would be great.
Here is a small example.
$opts = array(
'location' => 'http://xxxx/xxxxAPI',
'uri' => 'urn:http://test-uri/'
);
$client = new SOAPClient(null, $opts);
$headerData = array(
'FromSystemId' => 'CompanyName',
'UserName' => 'username',
'Password' => 'password',
);
// Create Soap Header.
$header = new SOAPHeader('http://xxxx/xxxxAPI', 'Auth', $headerData);
// Set the Headers of Soap Client.
$client->__setSoapHeaders($header);
$result = $client->__soapCall('getRegions', array('GB'));
// $return = $client->__soapCall('getRegions', array(new SoapParam(new SoapVar('GB', XSD_STRING), 'countryCode')));
var_dump($result);
They also haven't provided a WSDL, does this matter?
To be able to add the HEADER attributes they must be mentioned in WSDL. If they not exist in WSDL they WILL NOT appear as attributes but rather <item><key/><value/></item> elements.
Tipp: If you know how the request has to be and you have no WSDL, then try to generate the HTTP header and XML body manually and execute the request with CURL or Guzzle.
Example with Guzzle:
$soapContent = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<Auth xmlns="http://xxxx/xxxxAPI">
<FromSystemId ID="1">CompanyName</FromSystemId>
<UserName>username</UserName>
<Password>password</Password>
</Auth>
</soapenv:Header>
<soapenv:Body>
<GetRegions Timestamp="2016-04-11" Version="1.0" Lang="en"
xmlns="http://xxxx/xxxxAPI">
<Country Code="GB" />
</GetRegions>
</soapenv:Body>
</soapenv:Envelope>';
$client = new GuzzleHttp\Client([
'headers' => [ 'SOAPAction' => '"urn:http://xxxx/xxxxAPI/#getRegions"' ]
]);
$response = $client->post('http://xxxx/xxxxAPI',
['body' => $soapContent]
);
echo $response;

PHP Complexe Header with SoapClient()

I need to send Soap requests, but the server needs complex authentification and I don't no how create this header...
Target Soap structure :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:int="http://www.gmc.net/Phoenix/Integration">
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-2" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>user</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">pass</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<int:ListTicketsRequest>
<int:Company>test</int:Company>
</int:ListTicketsRequest>
</soapenv:Body>
</soapenv:Envelope>
My Php code
<?php
try
{
$wsdl = "https://aaa.wsdl";
$client = new SoapClient($wsdl, array('trace' => 1));
$header_part = '
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-2" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>user</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">pass</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
';
$soap_var_header = new SoapVar( $header_part, XSD_ANYXML, null, null, null );
$soap_header = new SoapHeader( 'http://your-target-service.com', 'wsse', $soap_var_header );
$client->__setSoapHeaders($soap_header);
$res = $client->ListTickets(array('Company' => 'test'));
}
catch (SoapFault $fault)
{
echo "SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring}) \n \n";
echo "====== REQUEST HEADERS =====" . PHP_EOL;
var_dump($client->__getLastRequestHeaders());
echo "========= REQUEST ==========" . PHP_EOL;
var_dump($client->__getLastRequest());
}
?>
My result
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.gmc.net/Phoenix/Integration" xmlns:ns2="http://your-target-service.com">
<SOAP-ENV:Header>
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-2" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>user</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">pass</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:ListTicketsRequest>
<ns1:Company>test</ns1:Company>
</ns1:ListTicketsRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Problems, Function SoapHeader need in first $data here 'http://your-target-service.com' (for testing). But my strucure include in native xmlns:ns1
Maybe my all my code is wrong..
I need your help !!
Thanks :)

Categories