Discussion:
PHP Soap mit TLS Zertifikat [API abfrage}
(zu alt für eine Antwort)
Timo
2022-09-10 02:12:28 UTC
Permalink
Guten Abend,

kurz eine kleine Vorabinfo:

Ich nutze IoT SIM Karten zur Überwachung meiner Weidezäune,
da es bei uns im Ort nicht so gut ankommt, wenn meine Schafherde mal
kurz einen Ausflug macht... ;-)

Da es mir leider schon zweimal passiert ist, dass das Datenvolumen
einzelner Karten aufgebraucht war und somit keine Datenübertragung
stattfinden konnte, möchte ich einmal am Tag die API des IoT Portals
abfragen, jedoch bin ich in Bezug auf "SOAP" nackter Anfänger.

Zum Problem:
Wenn ich den Echo Test der API wie folgt über die Shell abfrage,
bekomme ich eine korrekte Antwort.

==============
curl -X POST -H "Content-Type: application/json" \
-H "Accept-Encoding: gzip,deflate" \
-H "Cache-Control: no-cache" \
--cert customer-USER.cer \
--key customer-USER.key \
https://kiteplatform-api.telefonica.com:8010/services/REST/GlobalM2M/Echo/v1/r12/echo
-d '{"data":"test"}'
==============

Mein Problem ist jetzt, wie ich das in php bewerkstelligen kann.
Der Server läuft mit php8.0 und die Erweiterung php8.0-soap ist auch
installiert.

Leider findet man fast schon zu viele Beispiele zum SOAP_Client,
welche in Bezug auf TLS1.2 und dem übergeben der Zertifikate recht
schlecht dokumentiert sind. Gleiches gilt für php-curl.

Leider haben die ganzen Dokus und Manuals dazu geführt, dass ich jetzt
komplett nur noch Bahnhof verstehe im Bezug auf dem SOAP_Client.

Hat jemand von Euch eine Idee oder einen Lösungsansatz, den ich
verfolgen sollte?

Danke.

Gruß
Timo
Timo
2022-09-10 03:05:08 UTC
Permalink
Post by Timo
Hat jemand von Euch eine Idee oder einen Lösungsansatz, den ich
verfolgen sollte?
Ein Lösungsansatz war php-curl zu Beginn, da ich damit bereits andere
API's abrufe, jedoch scheitere ich hier bei der Einbindung das
Zertifikats und dem Schlüssel für die Authentifizierung:

==========================================
$url =
'https://kiteplatform-api.telefonica.com:8010/services/REST/GlobalM2M/Echo/v1/r12/echo';
$data = array(
"data" => "test"
);
$data_string = json_encode($data);
$ch=curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER,
array(
'Content-Type:application/json',
'Content-Length: ' . strlen($data_string)
)
);

$result = curl_exec($ch);
curl_close($ch);
==========================================

Ein weiterer Ansatz war dann via SoapClient, wobei es allerdinst auch
nicht wirklich funktioniert hat.

==========================================
$api_url =
"https://kiteplatform-api.telefonica.com:8010/services/REST/GlobalM2M/Echo/v1/r12/echo";

$stream_context_opts = array(
'http'=>array(
'method'=>"POST /services/REST/GlobalM2M/Echo/v1/r12/echo",
'header'=> "Content-Type: application/soap+xml; charset=utf-8\r\n",
'data' => "test\r\n"
)
);

$soap_stream_context = stream_context_create($stream_context_opts);

$soap_options = array(
'cache_wsdl' => WSDL_CACHE_NONE,
'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP,
'exceptions' => true,
'trace' => true,
'local_cert' => '/etc/certs/customer-USER.cer',
'soap_version' => 'SOAP_1_2',
stream_context' => $soap_stream_context,
'authentication' => SOAP_AUTHENTICATION_DIGEST
);

try {
$client = new SoapClient( $api_url, $options );
} catch (SoapFault $e) {
echo $e->getMessage();
}
==========================================

Gruß
Timo
Arno Welzel
2022-09-10 06:43:54 UTC
Permalink
Post by Timo
Guten Abend,
Ich nutze IoT SIM Karten zur Überwachung meiner Weidezäune,
da es bei uns im Ort nicht so gut ankommt, wenn meine Schafherde mal
kurz einen Ausflug macht... ;-)
Da es mir leider schon zweimal passiert ist, dass das Datenvolumen
einzelner Karten aufgebraucht war und somit keine Datenübertragung
stattfinden konnte, möchte ich einmal am Tag die API des IoT Portals
abfragen, jedoch bin ich in Bezug auf "SOAP" nackter Anfänger.
Wenn ich den Echo Test der API wie folgt über die Shell abfrage,
bekomme ich eine korrekte Antwort.
==============
curl -X POST -H "Content-Type: application/json" \
-H "Accept-Encoding: gzip,deflate" \
-H "Cache-Control: no-cache" \
--cert customer-USER.cer \
--key customer-USER.key \
https://kiteplatform-api.telefonica.com:8010/services/REST/GlobalM2M/Echo/v1/r12/echo
-d '{"data":"test"}'
==============
Mein Problem ist jetzt, wie ich das in php bewerkstelligen kann.
Der Server läuft mit php8.0 und die Erweiterung php8.0-soap ist auch
installiert.
Was spricht dagegen, obiges einfach mit shell_exec() auszuführen?

Siehe auch <https://www.php.net/manual/de/function.shell-exec.php>
--
Arno Welzel
https://arnowelzel.de
Timo
2022-09-10 19:20:56 UTC
Permalink
Hallo Arno,
danke für Deine Antwort.
Post by Arno Welzel
Was spricht dagegen, obiges einfach mit shell_exec() auszuführen?
Siehe auch <https://www.php.net/manual/de/function.shell-exec.php>
Nachdem ich jetzt mehrere Stunden damit vergeigt habe,
den SOAPClient zum Laufen zu bekommen, habe ich dann aber gesehen,
dass es auch eine REST API gibt, womit ich dann doch etwas besser klar
komme.

Mit php curl ist es die ganze Zeit an den Zertifikaten gescheitert,
die ich zur Authentifizierung übergeben muss.

Daher bin ich dann zu der Version via shell_exec übergegangen,
wobei dies zwar auf meinem Server aktiviert ist, aber bei vielen Hostern
ist dies natürlich gesperrt. Daher hatte ich es auch erst nicht in
Betracht gezogen. Aber jetzt läuft es.

============
$abfrage = 'curl -X GET -H "Content-Type: application/json" -H
"Accept-Encoding: gzip,deflate" -H "Cache-Control: no-cache" --cert
/var/api-certs/cert.pem --key /var/api-certs/cert.key
https://kiteplatform-api.telefonica.com:8010/serv...';

$output = shell_exec($abfrage);
============

Da bastel ich mir jetzt noch eine Classe drum herum und schon habe ich
alles was ich brauche, auch wenn es über shell_exec nicht die Beste
Lösung ist.

Gruß
Timo
Tim Ritberg
2022-09-10 20:51:15 UTC
Permalink
Post by Timo
Hallo Arno,
danke für Deine Antwort.
Post by Arno Welzel
Was spricht dagegen, obiges einfach mit shell_exec() auszuführen?
Siehe auch <https://www.php.net/manual/de/function.shell-exec.php>
Nachdem ich jetzt mehrere Stunden damit vergeigt habe,
den SOAPClient zum Laufen zu bekommen, habe ich dann aber gesehen,
dass es auch eine REST API gibt, womit ich dann doch etwas besser klar
komme.
Mit php curl ist es die ganze Zeit an den Zertifikaten gescheitert,
die ich zur Authentifizierung übergeben muss.
Also ein Client-Zertifikat?
Schon mal versucht auch die CA mitanzugeben?

https://stackoverflow.com/questions/11308270/using-curl-in-php-with-client-certificate-and-private-key-in-separate-files

Tim
Timo
2022-09-14 01:35:09 UTC
Permalink
Post by Tim Ritberg
Also ein Client-Zertifikat?
Genau.
Post by Tim Ritberg
Schon mal versucht auch die CA mitanzugeben?
https://stackoverflow.com/questions/11308270/using-curl-in-php-with-client-certificate-and-private-key-in-separate-files
Das hatte trotz CA-Zert. undauch mit CA-Bundle nicht wirklich
funktioniert. Daher lasse ich es vorerst über shell_exec läufen und
werde mich später noch einmal dran setzen.

Gruß
Timo
Arno Welzel
2022-09-11 12:01:19 UTC
Permalink
Timo, 2022-09-10 21:20:

[...]
Post by Timo
============
$abfrage = 'curl -X GET -H "Content-Type: application/json" -H
"Accept-Encoding: gzip,deflate" -H "Cache-Control: no-cache" --cert
/var/api-certs/cert.pem --key /var/api-certs/cert.key
https://kiteplatform-api.telefonica.com:8010/serv...';
$output = shell_exec($abfrage);
============
Da bastel ich mir jetzt noch eine Classe drum herum und schon habe ich
alles was ich brauche, auch wenn es über shell_exec nicht die Beste
Lösung ist.
Wenn die Nutzung fertige Bibliotheken kein Problem ist, wäre Guzzle noch
eine Alternative zu curl:

<https://docs.guzzlephp.org/en/stable/>

Da ist die Übergabe von Zertifikaten prinzipiell auch vorgesehen:

<https://docs.guzzlephp.org/en/stable/request-options.html#cert>
--
Arno Welzel
https://arnowelzel.de
Timo
2022-09-14 01:36:14 UTC
Permalink
Post by Arno Welzel
Wenn die Nutzung fertige Bibliotheken kein Problem ist, wäre Guzzle noch
<https://docs.guzzlephp.org/en/stable/>
<https://docs.guzzlephp.org/en/stable/request-options.html#cert>
Danke. Die Bibliothek werde ich mir mal ansehen.

Gruß
Timo

Loading...