Jump to content

Mischir

Members
  • Content Count

    2
  • Joined

  • Last visited

Everything posted by Mischir

  1. Hello,. I am currently trying to read data from Salesforce via REST Api. There is a working example for Postman that I would like to implement for a project in Delphi (12) / ICS 9.2 The process is as follows: 1) Sending the certificate (PFX) + password to the host 2) The server sends back session cookies when the certificate has been verified. 3) Sending the client ID and secret together with the session cookies from the previous session 4) In the response header is a code "Location: xyz" 5) This code is then used to request a token. 6) You receive the token and can then make requests via the REST API. 1) and 2) work exactly the same as in Postman. My problem is that the session cookies do not seem to be transferred correctly and a new session is created under 3) and no code is sent. It must be the same session. If I copy the "Location code" from Postman and paste it into the Delphi application, 5) and 6) also work. I have also uploaded the logging in the attachment. I think this is the problem: 14:20:28:879 NSCB> New session created 14:20:28:879 000001CB1A118B70 CliNewSessionCB [000001CB1B664740] Reused: False The session is no longer used. In Postman there stands in the console : TLS: reused=true Here is my Code in Delphi. I have added a few lines of code for logging (Memo and ICSLogger) Thanks, if anyone finds a mistake or something is missing. Mike procedure TForm1.Button6Click(Sender: TObject); var HTTPRest: TSslHttpRest; SslContext: TSslContext; CookieManager: TIcsCookies; ResponseStream: TMemoryStream; ResponseHeaders: TStringList; Cookies: TStringList; Url: string; ResponseText: TStringList; i: Integer; errs: string; CookieHeader: string; begin if OpenDialog1.Execute then begin ED_PFX_Cert_Dir.text := OpenDialog1.FileName; // clear Memo mResult.Clear; try CookieManager := TIcsCookies.Create(self); SslContext := TSslContext.Create(self); HTTPRest := TSslHttpRest.Create(self); try ResponseStream := TMemoryStream.Create; ResponseHeaders := TStringList.Create; Cookies := TStringList.Create; ResponseText := TStringList.Create; SslContext.SSLVerifyPeer := true; SslContext.SslVerifyPeerModes := [SslVerifyMode_PEER]; SslContext.SslSessionCacheModes := SslContext.SslSessionCacheModes + [sslSESS_CACHE_CLIENT]; HTTPRest.SslContext := SslContext; HTTPRest.OnSslVerifyPeer := SslHttpRest1SslVerifyPeer; HTTPRest.CertVerMethod := CertVerWinStore; HTTPRest.RestCookies.AutoSave := true; // necessary, because I use cookiemamager? HTTPRest.Connection := 'keep-alive'; CookieManager.AutoSave := true; HTTPRest.RestCookies := CookieManager; // Sending certificate HTTPRest.SslCliCert.LoadFromFileEx(ED_PFX_Cert_Dir.text, croYes, croTry, Ed_PW_Cert.text, errs); if errs <> '' then mResult.Lines.AddStrings(errs); // Logger if Form1.Chb_logging.Checked then begin IcsLogger1.LogFileName := TPath.GetSharedDocumentsPath + PathDelim + 'ICSLogger.txt'; HTTPRest.IcsLogger := IcsLogger1; HTTPRest.DebugLevel := DebugHdr; end; // Set up SSL context with client certificate, necessary ??? SslContext.SslCertFile := ED_PFX_Cert_Dir.text; SslContext.SslPassPhrase := Ed_PW_Cert.text; HTTPRest.Url := ED_Url.text + '/nidp/app/login'; HTTPRest.RcvdStream := ResponseStream; HTTPRest.FollowRelocation := true; HTTPRest.SslSessCache := true; // First request to get session cookies try HTTPRest.Get; mResult.Lines.Add('HTTP GET request succeeded.'); except on E: Exception do begin mResult.Lines.Add('Error with connection: ' + E.Message); end; end; mResult.Lines.Add(Format('Response Code: %d', [HTTPRest.StatusCode])); mResult.Lines.Add(Format('Response Text: %s', [HTTPRest.ReasonPhrase])); // Extract cookies from response headers for i := 0 to HTTPRest.RcvdHeader.Count - 1 do begin if Pos('Set-Cookie:', HTTPRest.RcvdHeader[i]) > 0 then begin Cookies.Add(Copy(HTTPRest.RcvdHeader[i], Length('Set-Cookie: ') + 1, MaxInt)); end; end; // Output the response headers ResponseHeaders.text := HTTPRest.RcvdHeader.text; mResult.Lines.AddStrings(ResponseHeaders); // Output the response content ResponseStream.Position := 0; ResponseText.LoadFromStream(ResponseStream); // Prepare the next request Url := 'https://XYZ.com/nidp/oauth/nam/authz'; HTTPRest.Url := Url + '?response_type=code&client_id=' + ED_ClientID.text + '&redirect_uri=https://localhost:443&scope=apim'; ED_Request.text := HTTPRest.Url; // Add cookies to the header of the second request // Loop through all cookies for i := 0 to CookieManager.Count - 1 do begin // Construct the cookie header string if CookieHeader <> '' then CookieHeader := CookieHeader + '; '; CookieHeader := CookieHeader + CookieManager.Get1Cookie(i).CName + '=' + CookieManager.Get1Cookie(i).CValue; end; // Add the cookie header to the ExtraHeaders if CookieHeader <> '' then HTTPRest.ExtraHeaders.AddPair('Cookie', CookieHeader); mResult.Lines.Add('Cookies from first request:'); mResult.Lines.Add(CookieHeader); // Log the final URL and headers mResult.Lines.Add('Final request URL: ' + HTTPRest.Url); mResult.Lines.Add('Final request headers:'); mResult.Lines.AddStrings(HTTPRest.ExtraHeaders); HTTPRest.FollowRelocation := false; // Important ! // Second request , to get the "code" in HEADER "Location". try HTTPRest.Get; mResult.Lines.Add('HTTP GET2 request succeeded.'); mResult.Lines.Add(Format('Response Code: %d', [HTTPRest.StatusCode])); mResult.Lines.Add(Format('Response Text: %s', [HTTPRest.ReasonPhrase])); // Loop through the headers and show them for i := 0 to HTTPRest.RcvdHeader.Count - 1 do mResult.Lines.Add(HTTPRest.RcvdHeader[i]); // Output the response content ResponseStream.Position := 0; ResponseText.LoadFromStream(ResponseStream); mResult.Lines.AddStrings(ResponseText); except on E: Exception do begin mResult.Lines.Add('Error with connection: ' + E.Message); end; end; finally ResponseHeaders.Free; ResponseStream.Free; Cookies.Free; ResponseText.Free; end; finally SslContext.Free; CookieManager.Free; HTTPRest.Free; end; end; end; ICSLogger.txt
  2. Hi Angus, Thanks for the tip! You saved my day 🙂 I used the code snippet from the OverbyteIcsSnippets doHttpRestReqClick and customized it a bit and it all works... and with just a few lines of code! Thanks for the quick support Regards, Mike
×