![]() |
Webservice + SSL + D2010
Hallo,
ich versuche gerade einen Webservice über HTTPS zu konsumieren. Leider funktioniert es nicht. Ich nutze dafür eigentlich nur die HTTPClient Komponente. Hier ein Beispiel welches problemlos funktioniert:
Code:
Hier der request in weather.xml:function TForm2.SendRequest(): string; var err, str: string; req: TStringStream; strings: TStringList; begin try strings := TStringList.Create; XMlDoc.XML.LoadFromFile('weather.xml'); strings.AddStrings(XMlDoc.XML); HttpClient.Request.URL := 'http://www.webservicex.net/WeatherForecast.asmx'; HttpClient.Request.Accept := 'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2'; HttpClient.Request.ContentType := 'application/soap+xml;charset=iso-8859-1;action="urn:sendblabla"'; req := TStringStream.Create(strings.GetText); try str := HttpClient.Post(HttpClient.Request.URL , req); except On E: EIdHTTPProtocolException do begin err := 'HTTP-Fehler: ' + E.Message; str := E.ErrorMessage; end; On E: Exception do err := 'Allgemeiner Fehler: ' + E.Message; end; finally strings.free; end; Result := str; end;
Code:
<?xml version='1.0' encoding='iso-8859-1'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:web="http://www.webservicex.net"> <soapenv:Header/> <soapenv:Body> <web:GetWeatherByPlaceName> <web:PlaceName>London</web:PlaceName> </web:GetWeatherByPlaceName> </soapenv:Body> </soapenv:Envelope> Nutze ich nun fast den selben Code für einen HTTPS Webservice bekomme ich immer die Fehlermeldung Soecketerror #0: Mein Code dafür sieht so aus:
Code:
Die header.txt sieht so aus:
var err, str: string;
req: TStringStream; strings, header: TStringList; SSLIOHandler: TIdSSLIOHandlerSocketOpenSSL; begin try SSLIOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(self); with SSLIOHandler do begin SSLOptions.Mode := sslmClient; SSLOptions.Method := sslvSSLv3; SSLOptions.VerifyMode := []; SSLOptions.VerifyDepth := 0; end; HttpClient.IOHandler := SSLIOHandler; header := TStringList.Create; header.LoadFromFile('header.txt'); HttpClient.Request.RawHeaders.Assign(header); strings := TStringList.Create; XmlDoc.XML.LoadFromFile('hsst.xml'); strings.AddStrings(XmlDoc.XML); HttpClient.BoundPort := 443; HttpClient.Request.URL := 'https://******************/webservice/********Service'; HttpClient.Request.Accept := 'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2'; HttpClient.Request.ContentType := 'application/soap+xml;charset=iso-8859-1;action="urn:sendBlabla"'; req := TStringStream.Create(strings.GetText); str := HttpClient.Post(HttpClient.Request.URL , req); except On E: EIdHTTPProtocolException do begin err := 'HTTP-Fehler: ' + E.Message; str := E.ErrorMessage; end; On E: Exception do err := 'Allgemeiner Fehler: ' + E.Message; end; strings.free; header.Free; SSLIOHandler.Free; mmo2.Text := str; end;
Code:
Anzumerken ist noch, dass der Webservice http Basic Authentifizierung erfordert, deshalb wurde in der header.txt auch Autorization base64 codiert.
POST https://********/webservice/*********** HTTP/1.1
Content-type: text/xml;charset="utf-8" Authorization: Basic ***************== Soapaction: "http://***********.de/abrufen*****" Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 Host: **********:443 Connection: keep-alive Content-Length: 719 Die hsst.xml beinhaltet hier die Soap-Nachricht, jedoch stimmt diese 100%, deshalb liste ich diese mal hier nicht auf. Hat jemand einen Rat warum es nicht funktioniert? Muss ich bei SSL und Webservices noch etwas beachten? Das interessante ist, dass ich den Service mit dem Tool SoapUI proplemlos nutzen kann. Ich weiß ist etwas viel, aber sitz jetzt schon 2 Tage dran und komm nicht mehr weiter. Wäre nett, wenn mir jemand helfen könnte. Vielen Dank. mc |
AW: Webservice + SSL + D2010
Hey mcbain,
sieht soweit vernünftig aus, welche Indy Version benutzt du denn? Etwa die die mit Delphi 2010 mitinstalliert wurde? Im EDN gibt es dazu ein Thread mit dem gleichen Fehler wie bei dir, kannst es dann ja mal mit einem Indy-Update probieren: ![]() Dies kannst du eigentlich weglassen:
Delphi-Quellcode:
Hier würde ich statt RawHeaders lieber CustomHeaders nehmen:
with SSLIOHandler do
begin SSLOptions.Mode := sslmClient; SSLOptions.Method := sslvSSLv3; SSLOptions.VerifyMode := []; SSLOptions.VerifyDepth := 0; end;
Delphi-Quellcode:
HttpClient.Request.RawHeaders.Assign(header);
hsst.xml kannst du auch direkt in den req:TStringStream laden :wink: Grüße |
AW: Webservice + SSL + D2010
Hallo Sebastian,
vielen Dank für deinen Tip. Ich habe die aktuelle Indy10 nun installiert und der Fehler ist weg. Jetzt habe ich nur noch das Problem, dass ich keine richtige Antwort vom Server bekomme. Ich bekomme keine XML Datei zurückgeschickt sondern HTML in dem steht "<h2>Es ist ein allgemeiner Fehler aufgetreten!</h2> <p>Leider kann Ihre Anfrage zur Zeit nicht bearbeitet werden. </p>" Das verstehe ich aber nicht, ich rufe in dem Tool SoapUI genau die gleiche URL auf wie in meinem httpclient.request.url property. Muss ich evtl. noch etwas mit dem Zertifikat anstellen? Wäre super, wenn du mir weiterhelfen könntest nochmal. Vielen Dank. mc |
AW: Webservice + SSL + D2010
Die Fehlermeldung kommt meiner Meinung nach durch 2 mögliche Fehlerquellen zustande. Entweder du sendest die Daten nicht richtig oder der Server/Script blockt dich weil es dich als Client nicht mag :wink:
Die einfachste Möglichkeit wäre den Datenverkehr von SoapUI zum Server mittels WireShark aufzunehmen und mit einer 2ten Instanz von WireShark den Verkehr von deinem Tool zum Server so weißt du nachher genau, was das andere Tool sendet, damit es klappt. Das dumme ist nur ich sehe gerade das ganze wird per HTTPS abgewickelt, da wirst du dann leider nicht so viel auslesen können :P Da muss man schon nach ![]() |
AW: Webservice + SSL + D2010
Ein gefaktes Zertifikat? In der Richtung habe ich noch nie etwas gemacht. Kannst du mir evtl. noch ein bisschen auf die Sprünge helfen?
Sorry, hab aber noch nicht so viel mit HTTPS realisiert. |
AW: Webservice + SSL + D2010
Wenn du dieses Fiddler installierst, dann gibt es in den Einstellungen einen Punkt, wo du dann draufklicken kannst und es wird ziemlich vollautomatisch ein gefaktes SSL Zertifikat installiert. Damit kann dann die Verbindung mitgeschnitten werden, da dafür dieses SSL Zertifikat benutzt wird. Jedoch wird Windows dir eingehend davon abraten.
Außerdem könntest du Probleme bekommen, wenn du am PC noch anderen Netzwerkaktivitäten wie normales Surfen und sowas wie ICQ am laufen hast. Nachher solltest du auch nochmal überprüfen ob das SSL-Zertifikat wieder sauber deinstalliert wurde. Wenn es nicht allzuviel Mühe macht würde ich fast sagen nimm' eine VM dafür. |
AW: Webservice + SSL + D2010
So, habe nun Fiddler mal installiert und HTTPS Decrypt aktiviert.
Leider kapier ich nicht ganz, wo mir jetzt nun der genaue Traffic angezeigt wird. Ich kann mit dem ResponseBuilder eine Anfrage erfolgreich absetzen, wie mit dem SoapUI Tool. Aber wie sehe ich jetzt genau was mein Delphi Programm absetzt und was Fiddler absetzt? Lasse ich mein Delphi Programm ablaufen zeichnet Fiddler nämlich nichts auf, obwohl es auf "Capture" steht. Es kann doch nur noch ein kleines Problem sein... Wäre super, wenn du mir nochmal helfen könntest. Vielen Dank. |
AW: Webservice + SSL + D2010
So, ich habe nun eine Lösung für mein Problem gefunden.
Ich habe nun ganz auf die Indy-Komponenten verzichtet. Die einzige Komponente ist ein HTTPRio. Hier der Code:
Code:
Als kleine Anmerkung, in der Unit EncdDecd sind Funktionen für die Base64 Kodierung/Enkodierung enthalten. Damit kann man für HTTP Autorization Header den Usernamen und Passwort umwandeln.
...
uses ... Rio, SOAPHTTPClient, WinInet , SOAPHttpTrans, EncdDecd, ... ... procedure TForm2.rioHTTPWebNode1BeforePost(const HTTPReqResp: THTTPReqResp; //Fügt den benötigten HTTP-Header hinzu für die Basic-Authentication Data: Pointer); var S: String; begin S := 'Authorization: Basic **************=='; //HTTP-Basic-Authorization-Header HttpAddRequestHeaders(Data, PChar(S), Length(S), HTTP_ADDREQ_FLAG_ADD); end; procedure TForm2.Button1Click(Sender: TObject); var request, response: TStringStream; strings: TStringList; str: string; recieveID: integer; begin rio.HTTPWebNode.URL := 'https://********************/webservice/***************Service'; //URL des Webservices rio.HTTPWebNode.SoapAction := 'http://**************/abrufen*************************'; //URL der aufzurufenden Methode rio.HTTPWebNode.Agent := 'Mozilla'; rio.Port := '443'; try strings := TStringList.Create; strings.LoadFromFile('request.xml'); //Hier ist der XML-request enthalten request := TStringStream.Create(strings.GetText); response := TStringStream.Create(''); recieveID := rio.HTTPWebNode.Send(request); //Request rio.HTTPWebNode.Receive(recieveID,response,false); //Response response.Position := 0; mmo2.Lines.LoadFromStream(response, TEncoding.UTF8); finally strings.Free; request.Free; response.Free; end; end; Ich hoffe, ich konnte jemandem damit helfen. Vielen Dank an Sebastian. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:53 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz