Archive for the ‘WebService’ Category

Powershell Fehlermeldung ConvertFrom-Json : Ungültiger JSON-Primitiv: ..

26 März 2018

Beim Versuch eine absolut simple JSON-Datei in Windows Powershell 5.1 einzulesen erschien die Fehlermeldung:

ConvertFrom-Json : Ungültiger JSON-Primitiv: ..
In Zeile:1 Zeichen:1
+ ConvertFrom-Json .\settings.json
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [ConvertFrom-Json], ArgumentException
    + FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand

Ich bin schon mehrfach über dieses Problem gestolpert, wie andere auch, jedoch war es noch nie so klar wie in diesem Fall, woran das Problem liegt. Wieso das Problem so offensichtlich gelöst werden konnte, lag daran, dass die JSON-Datei absolut simple war:

{
"files.encoding": "cp850"
}

Obwohl die Datei offensichtlich korrekt aussieht, beschwert sich ConvertFrom-JSON. Als ich mir dann die Datei in Hex angeschaut habe, wurde aber schnell offensichtlich was das Problem ist:

PS > Format-Hex .\settings.json

           Pfad: .\settings.json

           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000   7B 0A 20 20 20 20 22 66 69 6C 65 73 2E 65 6E 63  {.    "files.enc
00000010   6F 64 69 6E 67 22 3A 20 22 63 70 38 35 30 22 0A  oding": "cp850".
00000020   7D                                               }

Ich gebe zu, die Darstellung ist unter aller sau, Danke WordPress, aber das Entscheidende ist zu sehen. Es sind die markierten 0A für den Zeilenumbruch. 0A weil es sich um eine Datei aus der Linuxwelt handelt, da ist 0A als Zeilenumbruch üblich. Hat sich leider bis zur Version 5.1 von Powershell nicht bei Microsoft herumgesprochen. Erst Powershell 6 Core arbeitet hier korrekt.

Wenn ich nun also vor dem Aufruf mit ConvertFrom-Json die Zeilenumbrüche in Windowsverträgliche umwandle, dann klappt auch die JSON-Konvertierung:

(Get-Content .\settings.json) -replace 0x10, (0x13,0x10) |ConvertFrom-Json

files.encoding
————–
cp850

Hier der Beweis, dass die anderen Zeilenumbrüche gesetzt sind:

PS > (Get-Content .\settings.json) -replace 0x10, (0x13,0x10) |out-string | Format-Hex

           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000   7B 0D 0A 20 20 20 20 22 66 69 6C 65 73 2E 65 6E  {..    "files.en
00000010   63 6F 64 69 6E 67 22 3A 20 22 63 70 38 35 30 22  coding": "cp850"
00000020   0D 0A 7D 0D 0A                                   ..}..

Da viele REST-APIs von Linuxrechnern auch JSON-Dateien verteilen und davon auszugehen ist, dass diese ihre JSON-Dateien mit den unter Linux-üblichen Zeilenumbrüchen versehen, ist davon auszugehen, dass das Problem auch bei einfachen Invoke-WebRequest zum Thema wird, wie hier https://stackoverflow.com/questions/24453320/invalid-json-primitive-error-when-converting-json-file oder hier https://stackoverflow.com/questions/47908382/convertfrom-json-invalid-json-primitive-%C3%AF.

Wie gesagt mit Powershell Core 6.x ist das Thema ebenfalls erledigt.

REST Api Guidelines und OpenAPI

23 August 2017

Da heutzutage immer mehr Dienste direkt per HTTP-Aufrufe ansprechbar sind, haben alle großen Hersteller von Webdiensten mittlerweile API-Guidelines zur Erstellung dieser Dienste. Dies kann manchmal hilfreich sein, wenn es um kryptische Fehlermeldungen in Log-Dateien geht.

Hier der Verweis auf die API-Guidelines von Microsoft: https://github.com/Microsoft/api-guidelines/blob/vNext/Guidelines.md und von Google: https://cloud.google.com/apis/design/. Guidelines von Amazon konnte ich noch keine ausfindig machen, daher nur ein Link auf die aktuelle API: https://docs.aws.amazon.com/apigateway/api-reference/. Es gibt auch bereits Seiten, welche sich den Guidelines annehmen und diese wieder auf bestimmte Kriterien untersuchen zum besseren Vergleichen: http://apistylebook.com/design/guidelines/.

Ein Punkt der beim Datenaustausch zwischen verschiedenen APIs für Verwirrung sorgen könnte, sind Datumsfelder. Bei Google ist die Rede von RFC3339 (http://tools.ietf.org/html/rfc3339), bei Microsoft von ISO8601. Beide sind sich ähnlich allerdings unterscheiden sie sich in ein paar Kleinigkeiten, die im Zweifel wie immer alles durcheinander bringen können: https://stackoverflow.com/questions/522251/whats-the-difference-between-iso-8601-and-rfc-3339-date-formats.

Wo findet man nun diese Guidelines angewendet? Z. B. hier: https://cloud.google.com/apis/docs/overview oder beim Microsoft Graph: https://developer.microsoft.com/de-de/graph/docs/concepts/overview.

Wenn wir schon dabei sind, muss ich noch OpenAPI nennen, welches in Zukunft auch größere Bedeutung bekommen dürfte: https://www.openapis.org/specification/repo bzw. https://swagger.io/specification/. Als alter Powersheller sollte ich dabei noch gleich auf PSSwagger verweisen: https://github.com/PowerShell/PSSwagger. Mit PSSwagger lassen sich aus bestehenden OpenAPI-Definitionen automatisch Cmdlets erstellen. Wer es allgemeiner benötigt kann auch AutoRest von MS verwenden: https://github.com/Azure/autorest.

Wer wendet nun OpenAPIs bereits an? Na z. B. Google: https://cloud.google.com/endpoints/docs/openapi/. Auch Microsoft ist bei seinen Azure-Bemühungen mit dabei und hat sich klar zu OpenAPI bekannt: https://blogs.msdn.microsoft.com/apimanagement/2016/10/24/swaggers-success-gives-birth-to-openapi/.

Mit der aktuellen OpenAPI Spezifikation 3.0 dürfte nun der API-Zug endgültig den Bahnhof verlassen und schnell Fahrt aufnehmen…

Wenn ich irgendetwas zum Thema vergessen habe sollte, findet man es sicher hier. https://design.apievangelist.com/.

Bei Powershell SSL/TLS-Zertifikate-Prüfung einfach ignorieren

26 Juli 2014

Da alle Welt mittlerweile nach SSL/TLS-Transportverschlüsselung schreit, um die gröbsten Manipulationsmöglichkeiten während einer Datenübertragung, auszuschließen, bekommt man ein Problem, wenn man mal aus der Hüfte etwas ausprobieren möchte.

Aktueller Fall: Ein Web-Dienst soll kurz abgefragt werden um zu sehen, wie er reagiert. Aus Sicherheitsgründen ist dieser Dienst aber nur per HTTPS verfügbar, was zu folgendem Problem führt:

PS> Invoke-WebRequest -Uri "https://192.168.20.77:8802/cgi-bin/gadgetapi?cmd=Login&gsUser=14&gsPass=0815"
Invoke-WebRequest : Die zugrunde liegende Verbindung wurde geschlossen: Für den geschützten SSL/TLS-Kanal konnte keine Vertrauensstellung hergestellt werden..
In Zeile:1 Zeichen:1
+ Invoke-WebRequest -Uri "https://192.168.20.77:8802/cgi-bin/gadgetapi?cmd=Login&g
+ …~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
 

Eine simple und schnelle Lösung ist das Ausführen dieses Befehls:

add-type @"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
        public bool CheckValidationResult(
            ServicePoint srvPoint, X509Certificate certificate,
            WebRequest request, int certificateProblem) {
            return true;
        }
    }
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

Danach ist der angefragte Server zufrieden und liefert das gewünschte Ergebnis:

PS> Invoke-WebRequest -Uri "https://192.168.20.77:8802/cgi-bin/gadgetapi?cmd=Login&gsUser=14&gsPass=0815"
Invoke-WebRequest : Der Remoteserver hat einen Fehler zurückgegeben: (403) Unzulässig.
In Zeile:1 Zeichen:1
+ Invoke-WebRequest -Uri "https://192.168.20.77:8802/cgi-bin/gadgetapi?cmd=Login&g
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
 

OK, 403 ist nicht optimal aber es ging nur darum einen korrekten HTTP-Statuscode zu bekommen!

Weitere Infos zu Powershell und SSL/TLS-Zertifikate und wie man bei Problemen weitere Infos erhält, findet man hier: https://newyear2006.wordpress.com/2014/01/04/ssltls-fehler-in-powershell-bzw-wie-man-zertifikatsprobleme-unter-windows-analysieren-kann/