AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Probleme mit SOAP von 10.2.3 nach 10.3.1
Thema durchsuchen
Ansicht
Themen-Optionen

Probleme mit SOAP von 10.2.3 nach 10.3.1

Ein Thema von Bbommel · begonnen am 9. Aug 2019 · letzter Beitrag vom 13. Sep 2019
Antwort Antwort
Bbommel

Registriert seit: 27. Jun 2007
Ort: Köln
648 Beiträge
 
Delphi 12 Athens
 
#1

Probleme mit SOAP von 10.2.3 nach 10.3.1

  Alt 9. Aug 2019, 10:04
Hi,

weiß jemand, ob es bekannte Probleme mit REST in Rio 10.3.1 gibt, die es in Tokyo 10.2.3 noch nicht gab? Ich meine, ich hätte hier in den letzten Monaten auch mal entsprechende Berichte/Fragen vorbeirauschen sehen, konnte bei der Suche aber nichts finden.

Zunächst: auf meinem eigenen System bzw. auf einem Testsystem bei einem Partnerunternehmen funktioniert alles problemlos sowohl mit einer mit 10.2.3 als auch mit 10.3.1 erstellten Version des Programms.

Bei einem Kunden erscheint aber bei der mit 10.3.1 erzeugten Version nur folgende Fehlermeldung: "Fehler [Leeres Dokument]". Das heißt, ich bekomme hier offenbar gar keine Antwort. Kompiliere ich den aktuellen Programmstand mit 10.2.3 und schicke das dem Kunden, kann er wieder problemlos arbeiten.

Gibt es hier irgendwelche bekannten Probleme? Ich habe gesehen, dass die REST-Bibliothek im Hintergrund wohl ziemlich umgebaut wurde. Hatte jemand schon ein ähnliches Problem und das gelöst? Oder ist es sogar ein Bug, der ein 10.3.2 gefixt wurde?

Geändert von mkinzler (12. Sep 2019 um 12:52 Uhr) Grund: Titel auf Wunsch von TE geändert
  Mit Zitat antworten Zitat
Bbommel

Registriert seit: 27. Jun 2007
Ort: Köln
648 Beiträge
 
Delphi 12 Athens
 
#2

AW: Probleme mit REST von 10.2.3 nach 10.3.1

  Alt 3. Sep 2019, 15:54
Ein kleines Update zum Thema. Leider ist es noch nicht komplett gelöst, aber etwas weiter bin ich schon.

Mit dem Wechsel von 10.2.3 auf 10.3.1 wurden die SOAP-Bibliotheken von Delphi im Hintergrund für die Übertragung von WinInet auf die WinHttp-Api von Windows umgestellt. Dabei sind leider gleich mehrere Sachen kaputtgegangen, die aber immerhin zum Teil in 10.3.2 schon wieder repariert wurden.

Das erste: die Fehlermeldungen, die man bei Problemen mit SOAP in 10.3.1 bekommen hat, waren selbst leider auch fehlerhaft. Es kam die besagte Fehlermeldung "Leeres Dokument", welche ja nicht wirklich weiterhilft. Nach einem Update auf 10.3.2 erhält man eine hilfreichere Fehlermeldung: 401 Unauthorized.

Das führt zum zweiten (eigentlichen) Problem: Wenn der Web Service in einem lokalen Netz auf einem Windows-Server läuft, dann war es bisher möglich, sich mit den aktuellen Windows Credentials anzumelden (NTLM) - man musste nicht seperat noch einmal Benutzername und Passwort speichern. Diese Funktion ist auf dem Weg von 10.2.3 nach 10.3.1 ebenfalls kaputtgegangen, offenbar aber durch ein Problem in der WinHttp-Api, nicht in Delphi direkt (hier beschreibt ein User das Problem und einen möglichen Workaround bei Stackoverflow). In Delphi 10.3.2 gibt es eine neue Propperty im HTTPWebNode vom HTTPRio, nämlich "UseDefaultCredentials", welche genau das macht, was der User auf Stackoverflow als Patch vorgeschlagen hat. Bei einem ersten kurzen Test beim Kunden hat es allerdings leider noch nicht geholfen - ich bekomme weiterhin einen 401.

Wenn ich Benutzername und Pssswort manuell in meinem Programm angebe und damit die HTTPWebNode-Eigennschaften Username und Password setze, dann funktioniert übrigens in allen Delphi-Versionen (10.2.3, 10.3.1, 10.3.2) alles problemlos. Aber alle Login-Daten, die ich nicht speichern muss, finde ich gut und würde daher eigentlich gerne weiter die Windows-Anmeldung benutzen, was zumindest ja auch in 10.3.2 auch wieder funktionieren müsste.

Wenn jemand dazu also noch etwas weiß, dann gerne immer her mit Tipps und Infos. Ansonsten schreibe ich hier irgendwann mal drunter, wenn ich eine endgültige Lösung gefunden haben sollte.
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.060 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Probleme mit REST von 10.2.3 nach 10.3.1

  Alt 4. Sep 2019, 13:15
Vielen Dank für das Update. Das hilft gewiss den ein oder anderen zukünftigen Suchenden!
  Mit Zitat antworten Zitat
Bbommel

Registriert seit: 27. Jun 2007
Ort: Köln
648 Beiträge
 
Delphi 12 Athens
 
#4

AW: Probleme mit SOAP von 10.2.3 nach 10.3.1

  Alt 4. Sep 2019, 13:20
Gerade erst gemerkt: kann vielleicht mal ein Mod den Titel des Themas von "REST" nach "SOAP" ändern? Ich Dödel.
  Mit Zitat antworten Zitat
Bbommel

Registriert seit: 27. Jun 2007
Ort: Köln
648 Beiträge
 
Delphi 12 Athens
 
#5

AW: Probleme mit SOAP von 10.2.3 nach 10.3.1

  Alt 12. Sep 2019, 11:40
Vorweg die Bitte an einen Moderator: kann einer von euch Mods das Thema von "REST" nach "SOAP" umbenennen, damit es auch von anderen korrekt gefunden wird? Ich hatte damals beim Erstellen offenbar einen kleinen Aussetzer.

Ich habe die Lösung für das Problem. Leider ist es auch in Delphi Rio 10.3.2 noch immer ein Bug in der Unit System.Net.HttpClient.Win, den man nur gelöst bekommt, indem man eine eigene Version der Unit in sein Projekt einbaut und die entscheidende Stelle patcht. Wer bessere Lösungen hat, gerne melden.

Ich versuche nochmal, das Problem, den Fehler und eine mögliche Lösung kurz zusammenzufassen (dann braucht ihr die bisherigen Beiträge nicht unbedingt lesen):

Problem:
Es soll ein Web Service innerhalb eines Unternehmsnetzwerks genutzt werden. Der Web Service wird auf einem Windows Server gehostet (konkret geht es hier um Web Services von Microsoft Dynamics NAV) und verlangt eine Authentifizierung, damit er genutzt werden kann. Da das ganze innerhalb eines Unternehmensnetzwerk passiert, kann eigentlich NTLM/Kerberos für die Authentifizierung genutzt und dabei die Credentials das aktuellen Benutzers genutzt werden. Heißt vereinfacht: Windows kümmert sich im Hntergrund um die Anmeldung am Web Service und der Benutzer muss seine Login-Daten nicht erneut eingeben bzw. man muss sie nicht selber irgendwo speichern. Bis Delphi 10.2.3 funktionierte das meist problemlos, ab Delphi 10.3.1 hat Emba die ganzen SOAP-Bibliotheken technisch komplett umgebaut, um sie auf THTTPClient umzubauen. Damit wird unter Windows nun nicht mehr die API WinInet, sondern WinHttp benutzt.

Der Fehler:
Wenn WinHttp mit NTLM arbeitet, dann gibt es eine Option, welche steuert, ob es mit den aktuellen Benutzer-Credentials arbeiten soll oder ob man Benutzername/Passwort angeben muss. Diese Option heißt WINHTTP_OPTION_AUTOLOGON_POLICY. Weist man ihr den Wert WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW zu, dann benutzt die Bibliothek den aktuellen Benutzer für den Login und Benutzername/Passwort werden erst gar nicht abgefragt. Weist man der Option hingegen den Wert WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH zu, dann braucht man auf jeden Fall Benutzername/Passwort. In Rio 10.3.1 wurde das überhaupt nicht beachtet, somit war ein Login zum Web Service unter Benutzung des aktuellen Benutzers nicht möglich. In Rio 10.3.2 hat man versucht, das Problem anzugehen und die neue Eigenschaft "useDefaultCredentials" im THTTPClient und im WebNode eingeführt. Dann gibt es folgende Funktion:

Delphi-Quellcode:
procedure TWinHTTPRequest.SetWinLogonPolicy;
var
  LClient: TWinHTTPClient;
  LOption: DWORD;
begin
  LClient := TWinHTTPClient(FClient);
  if LClient.UseDefaultCredentials then
    LOption := WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW
  else
    LOption := WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH;
  WinHttpSetOption(FWRequest, WINHTTP_OPTION_AUTOLOGON_POLICY, @LOption, SizeOf(LOption));
end;
Sieht eigentlich super aus, funktioniert aber nicht. Das Problem ist, dass die das "UseDefaultCredentials" nicht einfach im THTTPClient speichern, sondern in einem Record, der wiederum irgendwie in einem Dictionary steckt - da war ich dann irgendwann mit meinem Latein oder meiner Geduld am Ende und es mag sich gerne noch mal jemand ansehen. Der Effekt ist jedenfalls der: man weist zwar in seinem Code dem UseDefaultCredentials ein "true" zu, aber wenn dann die Verbindung tatsächlich initialisiert und somit die obige Funktion aufgerufen wird, dann ist es trotzdem immer noch "false". Die Folge: die Option WINHTTP_OPTION_AUTOLOGON_POLICY wird auf den falschen Wert gesetzt und WinHttp erwartet einen Aufruf von "SetCredentials" mit manuell mitgegebenem Benutzernamen und Passwort.

(hässlicher) Workaround:
Aktuell fällt mir nichts besseres ein, als eine eigene Version der Unit in mein Projekt zu kopieren und dort die Funktion wie folgt anzupassen:

Delphi-Quellcode:
procedure TWinHTTPRequest.SetWinLogonPolicy;
var
  LClient: TWinHTTPClient;
  LOption: DWORD;
begin
  LClient := TWinHTTPClient(FClient);
  if LClient.UseDefaultCredentials or forceSecurityLevelLow then
    LOption := WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW
  else
    LOption := WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH;
  WriteDebugMessage('SetWinLogonPolicy: call WinHttpSetOption with Option '+IntToStr(LOption));
  WinHttpSetOption(FWRequest, WINHTTP_OPTION_AUTOLOGON_POLICY, @LOption, SizeOf(LOption));
end;
Der entscheidende Unterschied ist nur if LClient.UseDefaultCredentials or forceSecurityLevelLow then . Ich habe hier im interface-Teil noch eine globale Variable ergänzt und kann diese nun vom eigentlichen Programm aus auf true setzen, um das zu erreichen, was ja eigentlich "UseDefaultCredentials" selber tun sollte. Dann klappt ein Login am Server, ohne dass man Benutzername/Passwort irgendwo speichern und angeben muss.

Ich werde dann wohl mal einen Eintrag bei QC dazu machen...
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.060 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Probleme mit SOAP von 10.2.3 nach 10.3.1

  Alt 12. Sep 2019, 13:19
Sehr gut! Vielen Dank, dass du deine Erkenntnisse für die Nachwelt teilst.

Zusatzidee: Anstatt die ganze Unit zu kopieren, kannst du auch die Windows-Funktion WinHttpSetOption intercepten.
Siehe meine Beiträge hier: https://www.delphipraxis.net/198305-...-tls-win7.html
  Mit Zitat antworten Zitat
Bbommel

Registriert seit: 27. Jun 2007
Ort: Köln
648 Beiträge
 
Delphi 12 Athens
 
#7

AW: Probleme mit SOAP von 10.2.3 nach 10.3.1

  Alt 12. Sep 2019, 15:32
Danke für den Tipp. Das sieht dann in meiner Testanwendung so aus und funktioniert tatsächlich:
Delphi-Quellcode:
uses
  [...]
  DDetours, Winapi.WinHttp;
[...]

var
  TrampolinWinHttpSetOption: function(hInternet: HINTERNET; dwOption: DWORD;
                   lpBuffer: Pointer; dwBufferLength: DWORD): BOOL; stdcall=nil;

implementation

function InterceptWinHttpSetOption(hInternet: HINTERNET; dwOption: DWORD; lpBuffer: Pointer; dwBufferLength: DWORD): BOOL; stdcall;
var
  LOption: DWORD;
begin
  if dwOption=WINHTTP_OPTION_AUTOLOGON_POLICY then begin
    LOption := WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW;
    Result:=TrampolinWinHttpSetOption(hInternet, WINHTTP_OPTION_AUTOLOGON_POLICY, @LOption, SizeOf(LOption));
  end else
    Result:=TrampolinWinHttpSetOption(hInternet,dwOption,lpBuffer,dwBufferLength);
end;


{$R *.dfm}

[...]

procedure TmainSoapTest.FormCreate(Sender: TObject);

var
  strList: TStringList;

begin
  if not Assigned(TrampolinWinHttpSetOption) then
  begin
    @TrampolinWinHttpSetOption := InterceptCreate(@WinHttpSetOption, @InterceptWinHttpSetOption);
  end;
  [...]
end;
In einem echten Programm würde man vielleicht nicht ganz so rabiat vorgehen, sondern aus einer Programmkonfiguration abfragen, ob nicht vielleicht doch mit Benutzernamen/Passwort gearbeitet werden soll. Aber das Prinzip funktioniert. Jetzt muss ich mal in mich gehen, ob es mir lieber ist, eine zusätzliche externe Unit einzubinden (also DDetours) oder die ganze HTTClient.Win-Unit rabiat zu überschreiben. Hm. Ist ja hoffentlich nur bis zum nächsten Delphi-Update... Sinnvollere wäre wahrscheinlich wirklich die Sache mit dem Hook.

Hier noch das Ticket bei QC.
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
2.815 Beiträge
 
Delphi 12 Athens
 
#8

AW: Probleme mit SOAP von 10.2.3 nach 10.3.1

  Alt 12. Sep 2019, 18:37
Danke für das Erforschen und Publizieren der Lösung!

Nur die eine Frage bleibt noch offen: ist dieses Problem schon in QP erfasst,
damit es EMBT auch offiziell bekannt ist und hoffentlich in einer Folgeversion
behoben wird?
  Mit Zitat antworten Zitat
Bbommel

Registriert seit: 27. Jun 2007
Ort: Köln
648 Beiträge
 
Delphi 12 Athens
 
#9

AW: Probleme mit SOAP von 10.2.3 nach 10.3.1

  Alt 12. Sep 2019, 21:05
Nur die eine Frage bleibt noch offen: ist dieses Problem schon in QP erfasst, damit es EMBT auch offiziell bekannt ist und hoffentlich in einer Folgeversion behoben wird?
Jepp, steht am Ende meines letzten Posts, also direkt über deinem Beitrag. Ich hab zwar QC statt QP geschrieben, aber das sind doch bürgerliche Kategorien.

Hier nochmal der Link zum Eintrag im Quality Portal.
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
2.815 Beiträge
 
Delphi 12 Athens
 
#10

AW: Probleme mit SOAP von 10.2.3 nach 10.3.1

  Alt 13. Sep 2019, 17:29
Ja, genaues Lesen hätte mal wieder geholfen
Danke für's Erfassen des Problems!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:43 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz