AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Webservice + SSL + D2010

Ein Thema von mcbain · begonnen am 8. Sep 2011 · letzter Beitrag vom 14. Sep 2011
Antwort Antwort
mcbain

Registriert seit: 18. Mai 2011
50 Beiträge
 
#1

Webservice + SSL + D2010

  Alt 8. Sep 2011, 15:00
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:

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;
Hier der request in weather.xml:
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:
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;
Die header.txt sieht so aus:
Code:
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
Anzumerken ist noch, dass der Webservice http Basic Authentifizierung erfordert, deshalb wurde in der header.txt auch Autorization base64 codiert.
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
  Mit Zitat antworten Zitat
Benutzerbild von geskill
geskill

Registriert seit: 17. Feb 2007
Ort: NRW
420 Beiträge
 
Delphi 2010 Professional
 
#2

AW: Webservice + SSL + D2010

  Alt 8. Sep 2011, 16:17
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: https://forums.codegear.com/message....ssageID=124091

Dies kannst du eigentlich weglassen:
Delphi-Quellcode:
     with SSLIOHandler do
     begin
       SSLOptions.Mode := sslmClient;
       SSLOptions.Method := sslvSSLv3;
       SSLOptions.VerifyMode := [];
       SSLOptions.VerifyDepth := 0;
     end;
Hier würde ich statt RawHeaders lieber CustomHeaders nehmen:
HttpClient.Request.RawHeaders.Assign(header);

hsst.xml kannst du auch direkt in den req:TStringStream laden

Grüße
Sebastian
  Mit Zitat antworten Zitat
mcbain

Registriert seit: 18. Mai 2011
50 Beiträge
 
#3

AW: Webservice + SSL + D2010

  Alt 9. Sep 2011, 11:14
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
  Mit Zitat antworten Zitat
Benutzerbild von geskill
geskill

Registriert seit: 17. Feb 2007
Ort: NRW
420 Beiträge
 
Delphi 2010 Professional
 
#4

AW: Webservice + SSL + D2010

  Alt 9. Sep 2011, 11:54
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

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 Da muss man schon nach Fiddler greifen und ein gefaktes SSL Zertifikat in den Zertifikatsspeicher laden. Ist mit ein bisschen "fummelarbeit" verbunden, besonders nachher das aufräumen aber es geht auch und du kannst dir sicher sein, dass du zu 100% die Lösung bekommst.
Sebastian
  Mit Zitat antworten Zitat
mcbain

Registriert seit: 18. Mai 2011
50 Beiträge
 
#5

AW: Webservice + SSL + D2010

  Alt 9. Sep 2011, 12:29
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.
  Mit Zitat antworten Zitat
Benutzerbild von geskill
geskill

Registriert seit: 17. Feb 2007
Ort: NRW
420 Beiträge
 
Delphi 2010 Professional
 
#6

AW: Webservice + SSL + D2010

  Alt 9. Sep 2011, 18:06
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.
Sebastian
  Mit Zitat antworten Zitat
mcbain

Registriert seit: 18. Mai 2011
50 Beiträge
 
#7

AW: Webservice + SSL + D2010

  Alt 12. Sep 2011, 08:05
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.

Geändert von mcbain (12. Sep 2011 um 08:37 Uhr)
  Mit Zitat antworten Zitat
mcbain

Registriert seit: 18. Mai 2011
50 Beiträge
 
#8

AW: Webservice + SSL + D2010

  Alt 14. Sep 2011, 09:26
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:
...
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;
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.

Ich hoffe, ich konnte jemandem damit helfen.

Vielen Dank an Sebastian.

Geändert von mcbain (14. Sep 2011 um 09:37 Uhr)
  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 08:36 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