Instead of OAuth 2.0 use Service account in google APIs lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- andersonscinfo · 2020-09-17 21:43 Does anyone know if it is possible to communicate with google through service accounts Ex: {   "type": "service_account",   "project_id": "name",   "private_key_id": "4a5s4df54das5f4d54fd4",   "private_key": "-----BEGIN PRIVATE KEY----- \mdfmdmfdmadd54f54asd5f4ds54fd4saf1asd21f2asd1f2a1sdf21a5e4rf5ew45raed fsda1f2asd1f21we51rf2asef1asd2f12ae1f5we5rfew\n-----END PRIVATE KEY-----\n",   "client_email": "dialogflow-sdfd@agente- ss-e.iam.gserviceaccount.com",   "client_id": "45454545454",   "auth_uri": "https://accounts.google.com/o/oauth2/auth",   "token_uri": "https://oauth2.googleapis.com/token",   "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",   "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/dialogflow- sdfd%40agente-ss-e.iam.gserviceaccount.com" } ---------------------------------------------------------------------- ASBzone · 2020-09-18 00:29 Why do you say "instead of" when token and authentication method in your snippet indicate OAUTH 2.0 is being used? ---------------------------------------------------------------------- Thaddy · 2020-09-18 07:07 Quote from: ASBzone on September 18, 2020, 02:29:25 amWhy do you say "instead of" when token and authentication method in your snippet indicate OAUTH 2.0 is being used? Yes, correct, but I think he maybe means without two factor authentication. That is less and less possible for consumer software. ---------------------------------------------------------------------- andersonscinfo · 2020-09-18 10:19 actually not exactly how to authenticate as a service account, i'm kind of lost, i wanted to do this using only the fpc httpclient if it was possible. https://cloud.google.com/docs/authentication/production Att. ---------------------------------------------------------------------- Leledumbo · 2020-09-19 09:07 Quote from: andersonscinfo on September 18, 2020, 12:19:46 pmactually not exactly how to authenticate as a service account, i'm kind of lost, i wanted to do this using only the fpc httpclient if it was possible. https://cloud.google.com/docs/authentication/production Att. I think the page already explains quite detailed on how to authenticate using service accounts, both inside and outside Google Cloud environment. Basically generate a JSON key, point it with the specified environment variable when starting your program and that's it. Which part you don't understand? ---------------------------------------------------------------------- andersonscinfo · 2020-09-19 10:21 I tried to do it using fphttpclient, but I was unsuccessful. Att. ---------------------------------------------------------------------- Thaddy · 2020-09-19 10:35 Quote from: andersonscinfo on September 19, 2020, 12:21:29 pmI tried to do it using fphttpclient, but I was unsuccessful. Att. There should not be a problem with fphttpclient (that package even contains an example: the calendar) Can you show us in a brief but complete example where your problems are? I know of several problems that often show up: - forgetting to set allowredirects - using old OpenSSL versions OR forgetting to add the OpenSSL units at all. (the latter involves no programming, just adding) Is your key really valid? - forgetting to have a proper private key and a Google account. Again: the calendar example is a very good and working demo and serves as documentation to avoid most of the above issues. Extra note: use TLS 1.1 or higher, TLS 1.2 or higher preferred. Google does not accept legacy protocols or encryption.(as all of the major providers) And of course, set it up using the component properties, not just the JSON you provided. ---------------------------------------------------------------------- andersonscinfo · 2020-09-19 11:03 I'm not using google API code Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program project1; {$mode objfpc}{$H+} uses  {$IFDEF UNIX}  cthreads,  {$ENDIF}  Classes,  sysutils,  DateUtils,  fphttpclient,  opensslsockets,  Basic_Api, unit1;  function TokenHeader: string;begin  Result := TJSONObject.New()    .Put('alg', 'RS256')    .Put('typ', 'JWT')    .Put('kid', '45d4f54ad5fa5df45asdfadsfqregthtg454878798')    .Stringify();end; function TokenSign(const APrivateKey, APayload: string): string;var  VHeader: string;  VPayload: string;  VSignature: string;begin  VHeader := TokenHeader.EncodeBase64URL;  VPayload := APayload.EncodeBase64URL;  VSignature := (VHeader + '.' + VPayload).HMACSHA256(APrivateKey).EncodeBase64URL;  Result := VHeader + '.' + VPayload + '.' + VSignature;end; function TokenPayload(const VJSON: IJSONValue): string;var  VDate: TDateTime;begin  VDate := Now;  Result := TJSONObject.New()    .Put('iss', VJSON.Path('client_email', ''))    .Put('aud', 'https://accounts.google.com/o/oauth2/token')    .Put('iat', IntToStr(DateTimeToUnix(VDate, False)))    .Put('exp', IntToStr(DateTimeToUnix(VDate.IncreaseMinutes(30), False)))    .Stringify()end; var  VJSON: IJSONValue;  VPayload: string;  VToken: string;  VHttp: TFPHTTPClient;  VBody: TStrings;  VUrl: string;  VResponse: TStringStream;begin  VJSON := TJSONParser.New('agente-sc- nv9d-46509c843848.json', fmOpenReadWrite).Parse;    VPayload := TokenPayload(VJSON);   VToken:= TokenSign(VJSON.Path('private_key', ''), VPayload);                                          VHttp := TFPHTTPClient.Create(nil);  VBody := TStringList.Create;    VResponse := TStringStream.Create('');  try    try      VBody.AddPair('grant_type', 'urn:ietf:params:oauth:grant-type:jwt- bearer');      VBody.AddPair('assertion', VToken);       VUrl := 'https://accounts.google.com/o/oauth2/token';                                               VHttp.FormPost(VUrl, VBody, VResponse);       WriteLn(VResponse.DataString);      WriteLn('');     except      raise    end;  finally    FreeAndNil(VResponse);    FreeAndNil(VBody);    FreeAndNil(VHttp);  end;  end. ---------------------------------------------------------------------- Leledumbo · 2020-09-20 09:42 What response did you receive? ---------------------------------------------------------------------- andersonscinfo · 2020-09-20 10:34 now i'm getting this message. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Invalid JWT Signature ---------------------------------------------------------------------- ASBzone · 2020-09-20 18:15 Quote from: andersonscinfo on September 20, 2020, 12:34:19 pmnow i'm getting this message. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Invalid JWT SignatureRight now, you have people willing to help you.  I'd recommend that you provide more verbose info (like the code you are using, and the explicit errors being received). It's hard to do remote troubleshooting when all you have are guesses and "it doesn't work". ---------------------------------------------------------------------- andersonscinfo · 2020-09-20 20:57 Quote from: ASBzone on September 20, 2020, 08:15:31 pmQuote from: andersonscinfo on September 20, 2020, 12:34:19 pmnow i'm getting this message. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Invalid JWT SignatureRight now, you have people willing to help you.  I'd recommend that you provide more verbose info (like the code you are using, and the explicit errors being received). It's hard to do remote troubleshooting when all you have are guesses and "it doesn't work". I provided the code just above that I'm using, on the message, it's a json that returns exactly what I posted above too, some days already with this problem but the solution may be close, I believe the problem is with the encryption, which should be rs254 but i'm using sha254, so i have more information posted here again, for now thanks everyone. ---------------------------------------------------------------------- WayneSherman · 2020-10-20 21:00 Quote from: andersonscinfo on September 17, 2020, 11:43:10 pmDoes anyone know if it is possible to communicate with google through service accounts Recommend you ask on the fpc-devel mailing list.  Michael Van Canneyt has plans to add support. See this thread: https://www.mail-archive.com/fpc- devel@lists.freepascal.org/msg39850.html or here for same thread (but missing some posts?): https://lists.freepascal.org/pipermail/fpc-devel/2020-June/042912.html ---------------------------------------------------------------------- zamronypj · 2020-10-20 22:32 Quote from: andersonscinfo on September 19, 2020, 01:03:23 pmI'm not using google API code Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program project1; {$mode objfpc}{$H+} uses  {$IFDEF UNIX}  cthreads,  {$ENDIF}  Classes,  sysutils,  DateUtils,  fphttpclient,  opensslsockets,  Basic_Api, unit1;  function TokenHeader: string;begin  Result := TJSONObject.New()    .Put('alg', 'RS256')    .Put('typ', 'JWT')    .Put('kid', '45d4f54ad5fa5df45asdfadsfqregthtg454878798')    .Stringify();end; function TokenSign(const APrivateKey, APayload: string): string;var  VHeader: string;  VPayload: string;  VSignature: string;begin  VHeader := TokenHeader.EncodeBase64URL;  VPayload := APayload.EncodeBase64URL;  VSignature := (VHeader + '.' + VPayload).HMACSHA256(APrivateKey).EncodeBase64URL;  Result := VHeader + '.' + VPayload + '.' + VSignature;end; function TokenPayload(const VJSON: IJSONValue): string;var  VDate: TDateTime;begin  VDate := Now;  Result := TJSONObject.New()    .Put('iss', VJSON.Path('client_email', ''))    .Put('aud', 'https://accounts.google.com/o/oauth2/token')    .Put('iat', IntToStr(DateTimeToUnix(VDate, False)))    .Put('exp', IntToStr(DateTimeToUnix(VDate.IncreaseMinutes(30), False)))    .Stringify()end; var  VJSON: IJSONValue;  VPayload: string;  VToken: string;  VHttp: TFPHTTPClient;  VBody: TStrings;  VUrl: string;  VResponse: TStringStream;begin  VJSON := TJSONParser.New('agente-sc- nv9d-46509c843848.json', fmOpenReadWrite).Parse;    VPayload := TokenPayload(VJSON);   VToken:= TokenSign(VJSON.Path('private_key', ''), VPayload);                                          VHttp := TFPHTTPClient.Create(nil);  VBody := TStringList.Create;    VResponse := TStringStream.Create('');  try    try      VBody.AddPair('grant_type', 'urn:ietf:params:oauth:grant-type:jwt- bearer');      VBody.AddPair('assertion', VToken);       VUrl := 'https://accounts.google.com/o/oauth2/token';                                               VHttp.FormPost(VUrl, VBody, VResponse);       WriteLn(VResponse.DataString);      WriteLn('');     except      raise    end;  finally    FreeAndNil(VResponse);    FreeAndNil(VBody);    FreeAndNil(VHttp);  end;  end.  you sign JWT with HMAC SHA 256 but set alg to RS256. It should be HS256. Read https.jwt.io for more information.