soap + ssl/TSL

0

Witam!

Próbuję połączyć się przez ssl z jedną usługą soap ale ciągle mam błąd na etapie łączenia ssl.

Czy ktoś miał może podobny problem do mojego ?

Załączam kod:

IdSSLIOHandlerSocketOpenSSL1.Open;

 IdSSLIOHandlerSocketOpenSSL1.DefaultPort:=443;

 IdSSLIOHandlerSocketOpenSSL1.Port:=443;
 IdSSLIOHandlerSocketOpenSSL1.Host:='https://dpdservicesdemo.dpd.com.pl/';
 IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method := sslvTLSv1;

 IdSSLIOHandlerSocketOpenSSL1.SSLOptions.VerifyMode := [];

 IdSSLIOHandlerSocketOpenSSL1.StartSSL;

aktualnie pojawia się błąd range check error i nie wiem co dalej.

z góry dzięki za pomoc.

0

http://www.scribd.com/doc/6550904/Indy-Soap-Web-Services-in-Delphi
BTW co twój kod ma wspólnego z SOAP? I oczywiście masz certyfikat żeby się z serwerem połączyć

0

no nieźle się wyłożyłem - aż wstyd.
Ogromne dzięki za materiał. Chciał bym się tylko upewnić czy jest ok. Certyfikat zaimportowałem ze strony z którą się łączę i dałem w miejscu certFile. Nie wiem tylko jeszcze jak zrobić keyfile (prywtany klucz ale to doczytam w książce)

obecny problem.
Zgodnie z instrukcją napisałem dwa unity - idsoaphttptrans i idsoaphttpclient. Mam delpgi 2009 więc indy 10 i zgodnie z tym modyfikowałem kod.

Pojawia się błąd o treści " IOHandler value is not valid "

Coś nie tak robią z uchwytem, W insrukcji pisze żeby używać go tak, jak httprio i tak robię. Chyba to kwestia klucza ale pewny nie jestem

Poniżej obecny kod (tylko zmieniłem hasła do logowania):

Var // zmienne


  SoapClient: TidHTTPRIO;
  SSLRequired: Boolean;

Dane_logowania : authDataV1;

Dane_paczek : openumlfeV1;

Paczki : array_of_parcelOpenUmlFeV1;

Dane_odbiorcy : PackageAddressOpenUMLFeV1;

Dane_nadawcy :PackageAddressOpenUMLFeV1;

Obsloga_bledow : pkgNumsGenerationPolicyV1;

Numer_paczki : PackagesGenerationResponseV1;

opcje_dodatkowe : servicesOpenUMLFeV2;

http : TIdHTTP;

SoapClientOnLog : Tidhttpreqresponlog;

begin



// tryb obsługi błędów


Obsloga_bledow := dpd2.pkgNumsGenerationPolicyV1.STOP_ON_FIRST_ERROR;




// Nowa paczka     -
SetLength(dane_paczek,1);
Dane_paczek[0] := dpd2.packages.Create;  // twoży packages

// unikatowe oznaczenie paczki
Dane_paczek[0].reference := 'nazwa unikalna';

// Paczki - dane przesyłek
SetLength(Paczki,1);
Paczki[0] := dpd2.ParcelOpenUMLFev1.Create;  // Tworzy parcele


Paczki[0].content := 'Koment';

Paczki[0].customerData1 := 'sadfa2sdf';
Paczki[0].customerData2 := 'sadf2asdf';
Paczki[0].customerData3 := 'sadfa22sdf';


Paczki[0].sizeX := 1;
Paczki[0].sizeY := 2;
Paczki[0].sizeZ := 3;

Paczki[0].weight := 12.20;


Dane_paczek[0].parcels := Paczki;

// kto płaci ?

Dane_paczek[0].payerType := dpd2.payerTypeEnumOpenUMLFeV1.SENDER;// nadawca płaci


// Dane klienta - odbiorcy - bez fidu

Dane_odbiorcy := dpd2.PackageAddressOpenUMLFeV1.Create;
Dane_odbiorcy.company := 'nazwa firmy';
Dane_odbiorcy.address := 'adres firmy';
Dane_odbiorcy.postalCode := '82300';
Dane_odbiorcy.city := 'miasto';
Dane_odbiorcy.phone := 'Telefon';
Dane_odbiorcy.countryCode := 'PL';


Dane_paczek[0].receiver := dane_odbiorcy;



// Dane nadawcy

Dane_nadawcy := dpd2.PackageAddressOpenUMLFeV1.Create;
//Dane_nadawcy.company := 'hs2222';
//Dane_nadawcy.address := 'ulica 8';
//Dane_nadawcy.city := 'Elbląg';
Dane_nadawcy.fid := 1495;
//Dane_nadawcy.postalCode := '82300';
//Dane_nadawcy.phone := '00000000';
//Dane_nadawcy.countryCode := 'PL';

Dane_paczek[0].sender := Dane_nadawcy;

// Pola referentycjne
Dane_paczek[0].ref1 := 'f vat';
Dane_paczek[0].ref2 := 'f vat1';
Dane_paczek[0].ref3 := 'f vat2';

// Dodatkowe opcje jak pobranie irp

opcje_dodatkowe := servicesOpenUMLFeV2.Create;


Dane_paczek[0].services := opcje_dodatkowe;


// Dane logowania

Dane_logowania := dpd2.authDatav1.Create;


Dane_logowania.login :=  'login';
Dane_logowania.password := 'haslo';
Dane_logowania.masterFid := 1234;


 SoapClient:= TIdHTTPRIO.Create(Self);



 with SoapClient.HTTPWebNode.HttpClient do
  begin
    AllowCookies:= True;
    HandleRedirects:= False;
    ProtocolVersion:= pv1_1;

    if not SSLRequired then
      begin  // HTTP
        {$IFDEF INDY10}
        CreateIOHandler(nil);
        {$ELSE}
    //    IOHandler.Free;
      //  IOHandler:= nil;
        {$ENDIF}
      end
    else


      begin  // HTTPS

        IOHandler:= TIdSSLIOHandlerSocketOpenSSL.Create(SoapClient.HTTPWebNode.HttpClient);

        with
             TIdSSLIOHandlerSocketOpenSSL(IOHandler), SSLOptions do
        begin
          Method:= sslvTLSv1;   // select SSL method
          CertFile:= 'my.cer';  // assign certificate
          KeyFile:= 'my';   // assign private key
          RootCertFile:= 'my.cer';

       // select verification method for server certificate
          VerifyMode:= [sslvrfClientOnce];//  sslvrfPeer, sslvrfFailIfNoPeerCert, ];
          VerifyDepth:= 1;
          OnVerifyPeer := OnVerifyPeer;  // było doonverifypeer
        end;
      end;



    end;

 SoapClient.HTTPWebNode.OnLog:= SoapClientOnLog;  // custom logging
// set correct ReadTimeout
  TIdTCPClient(SoapClient.HTTPWebNode.HttpClient).OnConnected:=  HttpClientOnConnected;



soapclient.WSDLLocation := 'https://dpdservicesdemo.dpd.com.pl/DPDPackageObjServicesService/DPDPackageObjServices?wsdl';
soapclient.Port := 'DPDPackageObjServicesPort';
soapclient.Service := 'DPDPackageObjServicesService';

Numer_paczki := (SoapClient as DPDPackageObjServices).generatePackagesNumbersV1(dane_paczek,Obsloga_bledow,dane_logowania);


end;

 

błąd pojawia się w unicie idhttp.pas w części:

     // Just check can we do SSL
      if not (IOHandler is TIdSSLIOHandlerSocketBase) then begin
        raise EIdIOHandlerPropInvalid.Create(RSIOHandlerPropInvalid); // tutaj podświetla błąd
      end;
      TIdSSLIOHandlerSocketBase(IOHandler).PassThrough := False;
      Result := ctSSL;

zdaje się że nie w porę wywołuję web services firmy dpd

user image

I na końcu zrzut ekranu z analizy pakietów- wygląda na to że nawiązuję połączenie ssl ale pewny nie jestem bo połączenie ssl w soap to dla mnie nowość. W razie gdyby ktoś potrzebował pomocy ze standardowym soapem łączącym się przez http niechaj pisze a pomogę bo w delphi jestem hobbystą od chyba 7 lat (wcześniej na prośbę szwagra oprogramowałem mu webapi allegro, teraz pora na webapi kuriera bo to coś nowego )

0

SSLRequired ustawiasz na true??

0

dzięki za nakierowanie - przeoczyłem tą zmienną.

jak uda mi się ruszyć ten kod żeby działał zamieszczę go co by inni nie musieli tyle kombinować.

Teraz znalazłem stronę:
http://blog.csdn.net/happy4nothing/article/details/201265

i chyba na niej będzie rozwiązanie nowego problemu.

Teraz pojawia się błąd certificate veryfy faild - poniżej obecny kod źródłowy.
Problem chyba w formacie certyfikatu (testowałem foraty pem i cer)

 procedure TForm50.Button1Click(Sender: TObject);
Var // zmienne


  SoapClient: TidHTTPRIO;
  SSLRequired: Boolean;

Dane_logowania : authDataV1;

Dane_paczek : openumlfeV1;

Paczki : array_of_parcelOpenUmlFeV1;

Dane_odbiorcy : PackageAddressOpenUMLFeV1;

Dane_nadawcy :PackageAddressOpenUMLFeV1;

Obsloga_bledow : pkgNumsGenerationPolicyV1;

Numer_paczki : PackagesGenerationResponseV1;

opcje_dodatkowe : servicesOpenUMLFeV2;

http : TIdHTTP;

SoapClientOnLog : Tidhttpreqresponlog;

begin



// tryb obsługi błędów


Obsloga_bledow := dpd2.pkgNumsGenerationPolicyV1.STOP_ON_FIRST_ERROR;




// Nowa paczka     -
SetLength(dane_paczek,1);
Dane_paczek[0] := dpd2.packages.Create;  // twoży packages

// unikatowe oznaczenie paczki
Dane_paczek[0].reference := 'nazwa unikalna';

// Paczki - dane przesyłek
SetLength(Paczki,1);
Paczki[0] := dpd2.ParcelOpenUMLFev1.Create;  // Tworzy parcele


Paczki[0].content := 'Koment';

Paczki[0].customerData1 := 'sadfa2sdf';
Paczki[0].customerData2 := 'sadf2asdf';
Paczki[0].customerData3 := 'sadfa22sdf';


Paczki[0].sizeX := 1;
Paczki[0].sizeY := 2;
Paczki[0].sizeZ := 3;

Paczki[0].weight := 12.20;


Dane_paczek[0].parcels := Paczki;

// kto płaci ?

Dane_paczek[0].payerType := dpd2.payerTypeEnumOpenUMLFeV1.SENDER;// nadawca płaci


// Dane klienta - odbiorcy - bez fidu

Dane_odbiorcy := dpd2.PackageAddressOpenUMLFeV1.Create;
Dane_odbiorcy.company := 'nazwa firmy';
Dane_odbiorcy.address := 'adres firmy';
Dane_odbiorcy.postalCode := '82300';
Dane_odbiorcy.city := 'miasto';
Dane_odbiorcy.phone := 'Telefon';
Dane_odbiorcy.countryCode := 'PL';


Dane_paczek[0].receiver := dane_odbiorcy;



// Dane nadawcy

Dane_nadawcy := dpd2.PackageAddressOpenUMLFeV1.Create;
//Dane_nadawcy.company := 'Turbo';
//Dane_nadawcy.address := 'ulica8';
//Dane_nadawcy.city := 'Elbląg';
Dane_nadawcy.fid := 1495;
//Dane_nadawcy.postalCode := '82300';
//Dane_nadawcy.phone := '794910919';
//Dane_nadawcy.countryCode := 'PL';

Dane_paczek[0].sender := Dane_nadawcy;

// Pola referentycjne
Dane_paczek[0].ref1 := 'f vat';
Dane_paczek[0].ref2 := 'f vat1';
Dane_paczek[0].ref3 := 'f vat2';

// Dodatkowe opcje jak pobranie irp

opcje_dodatkowe := servicesOpenUMLFeV2.Create;


Dane_paczek[0].services := opcje_dodatkowe;


// Dane logowania

Dane_logowania := dpd2.authDatav1.Create;


Dane_logowania.login :=  '1234';
Dane_logowania.password := '1234';
Dane_logowania.masterFid := 1234;


 SoapClient:= TIdHTTPRIO.Create(Self);

 sslrequired := true;


 with SoapClient.HTTPWebNode.HttpClient do
  begin
    AllowCookies:= True;
    HandleRedirects:= False;
    ProtocolVersion:= pv1_1;

    if not SSLRequired then
      begin  // HTTP

        CreateIOHandler(nil);

      end
    else


      begin  // HTTPS

        IOHandler:= TIdSSLIOHandlerSocketOpenSSL.Create(SoapClient.HTTPWebNode.HttpClient);



        with
             TIdSSLIOHandlerSocketOpenSSL(IOHandler), SSLOptions do
        begin
          Method:= sslvTLSv1;   // select SSL method
         CertFile:= 'my2.pem';  // assign certificate
         KeyFile:= '';   // assign private key
        RootCertFile:= 'my2.pem';

       // select verification method for server certificate

          VerifyMode:= [sslvrfPeer,  sslvrfPeer, sslvrfFailIfNoPeerCert ];
          VerifyDepth:= 1;
        //  OnVerifyPeer := OnVerifyPeer;  // było doonverifypeer

        end;
      end;



    end;

 SoapClient.HTTPWebNode.OnLog:= SoapClientOnLog;  // custom logging
// set correct ReadTimeout
  TIdTCPClient(SoapClient.HTTPWebNode.HttpClient).OnConnected:=  HttpClientOnConnected;

soapclient.WSDLLocation := 'https://dpdservicesdemo.dpd.com.pl/DPDPackageObjServicesService/DPDPackageObjServices?wsdl';
soapclient.Port := 'DPDPackageObjServicesPort';
soapclient.Service := 'DPDPackageObjServicesService';


Numer_paczki := (soapclient as DPDPackageObjServices).generatePackagesNumbersV1(dane_paczek,Obsloga_bledow,dane_logowania);



memo2.Clear;
memo2.Text := numer_paczki.packages[0].parcels[0].waybill;


0

Problem prawdopodobnie rozwiązany.

Standarwowe httprio1 ma zaimplementowane w sobie też obsługę przez zwykłe https które nie wymaga certyfikatu klienta. Kod który jest wyżej jest funkcjonalny dla wersji z logowaniem z użyciem specjalnego certyfikatu klienta.

Problem jest po stronie serwera gdzie wysyłam żądanie. Pobrałem narzędzie do analizy pakietów jakie wysyłam - pliczek xml jest wyrzeźbiony idealnie przez wdsl i komunikat błędu jest odczytywany zatem samo połączenie pięknie działa. W mojej ocenie problem leży gdzieś w danych jakie wysyłam, pewnie czegoś w nich brakuje w pliku xml, podobne przeszkody miałem gdy oprogramowałem webapi allegro.

1 użytkowników online, w tym zalogowanych: 0, gości: 1