Recent

Author Topic: Instead of OAuth 2.0 use Service account in google APIs  (Read 1061 times)

andersonscinfo

  • Full Member
  • ***
  • Posts: 112
Instead of OAuth 2.0 use Service account in google APIs
« on: September 17, 2020, 11:43:10 pm »
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-----\mdfmdmfdmadd54f54asd5f4ds54fd4saf1asd21f2asd1f2a1sdf21a5e4rf5ew45raedfsda1f2asd1f21we51rf2asef1asd2f12ae1f5we5rfew\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

  • Sr. Member
  • ****
  • Posts: 479
  • Automation leads to relaxation...
    • Free Console Utilities for Windows from BrainWaveCC
Re: Instead of OAuth 2.0 use Service account in google APIs
« Reply #1 on: September 18, 2020, 02:29:25 am »
Why do you say "instead of" when token and authentication method in your snippet indicate OAUTH 2.0 is being used?
-ASB: https://www.BrainWaveCC.com

Lazarus v2.0.11 r64032 / FPC v3.2.1-r47152 (via FpcUpDeluxe) -- Windows 64-bit install w/32-bit cross-compile
Primary System: Windows 10 Pro x64, Version 2009 (Build 19042)
Other Systems: Windows 10 Pro x64, Version 2004 (Build 19041) or greater

Thaddy

  • Hero Member
  • *****
  • Posts: 10574
Re: Instead of OAuth 2.0 use Service account in google APIs
« Reply #2 on: September 18, 2020, 09:07:02 am »
Why 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.
« Last Edit: September 18, 2020, 09:08:50 am by Thaddy »

andersonscinfo

  • Full Member
  • ***
  • Posts: 112
Re: Instead of OAuth 2.0 use Service account in google APIs
« Reply #3 on: September 18, 2020, 12:19:46 pm »
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

  • Hero Member
  • *****
  • Posts: 8279
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Instead of OAuth 2.0 use Service account in google APIs
« Reply #4 on: September 19, 2020, 11:07:00 am »
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.
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

  • Full Member
  • ***
  • Posts: 112
Re: Instead of OAuth 2.0 use Service account in google APIs
« Reply #5 on: September 19, 2020, 12:21:29 pm »
I tried to do it using fphttpclient, but I was unsuccessful.

Att.

Thaddy

  • Hero Member
  • *****
  • Posts: 10574
Re: Instead of OAuth 2.0 use Service account in google APIs
« Reply #6 on: September 19, 2020, 12:35:52 pm »
I 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.
« Last Edit: September 19, 2020, 12:50:49 pm by Thaddy »

andersonscinfo

  • Full Member
  • ***
  • Posts: 112
Re: Instead of OAuth 2.0 use Service account in google APIs
« Reply #7 on: September 19, 2020, 01:03:23 pm »
I'm not using google API

code
Code: Pascal  [Select][+][-]
  1. program project1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   {$IFDEF UNIX}
  7.   cthreads,
  8.   {$ENDIF}
  9.   Classes,
  10.   sysutils,
  11.   DateUtils,
  12.   fphttpclient,
  13.   opensslsockets,
  14.   Basic_Api, unit1;
  15.  
  16.  
  17. function TokenHeader: string;
  18. begin
  19.   Result := TJSONObject.New()
  20.     .Put('alg', 'RS256')
  21.     .Put('typ', 'JWT')
  22.     .Put('kid', '45d4f54ad5fa5df45asdfadsfqregthtg454878798')
  23.     .Stringify();
  24. end;
  25.  
  26. function TokenSign(const APrivateKey, APayload: string): string;
  27. var
  28.   VHeader: string;
  29.   VPayload: string;
  30.   VSignature: string;
  31. begin
  32.   VHeader := TokenHeader.EncodeBase64URL;
  33.   VPayload := APayload.EncodeBase64URL;
  34.   VSignature := (VHeader + '.' + VPayload).HMACSHA256(APrivateKey).EncodeBase64URL;
  35.   Result := VHeader + '.' + VPayload + '.' + VSignature;
  36. end;
  37.  
  38. function TokenPayload(const VJSON: IJSONValue): string;
  39. var
  40.   VDate: TDateTime;
  41. begin
  42.   VDate := Now;
  43.   Result := TJSONObject.New()
  44.     .Put('iss', VJSON.Path('client_email', ''))
  45.     .Put('aud', 'https://accounts.google.com/o/oauth2/token')
  46.     .Put('iat', IntToStr(DateTimeToUnix(VDate, False)))
  47.     .Put('exp', IntToStr(DateTimeToUnix(VDate.IncreaseMinutes(30), False)))
  48.     .Stringify()
  49. end;
  50.  
  51. var
  52.   VJSON: IJSONValue;
  53.   VPayload: string;
  54.   VToken: string;
  55.   VHttp: TFPHTTPClient;
  56.   VBody: TStrings;
  57.   VUrl: string;
  58.   VResponse: TStringStream;
  59. begin
  60.   VJSON := TJSONParser.New('agente-sc-nv9d-46509c843848.json', fmOpenReadWrite).Parse;  
  61.   VPayload := TokenPayload(VJSON);
  62.   VToken:= TokenSign(VJSON.Path('private_key', ''), VPayload);
  63.  
  64.  
  65.                                      
  66.   VHttp := TFPHTTPClient.Create(nil);
  67.   VBody := TStringList.Create;  
  68.   VResponse := TStringStream.Create('');
  69.   try
  70.     try
  71.       VBody.AddPair('grant_type', 'urn:ietf:params:oauth:grant-type:jwt-bearer');
  72.       VBody.AddPair('assertion', VToken);
  73.  
  74.       VUrl := 'https://accounts.google.com/o/oauth2/token';
  75.                                            
  76.       VHttp.FormPost(VUrl, VBody, VResponse);
  77.  
  78.       WriteLn(VResponse.DataString);
  79.       WriteLn('');
  80.  
  81.     except
  82.       raise
  83.     end;
  84.   finally
  85.     FreeAndNil(VResponse);
  86.     FreeAndNil(VBody);
  87.     FreeAndNil(VHttp);
  88.   end;
  89.  
  90.  
  91. end.
  92.  

Leledumbo

  • Hero Member
  • *****
  • Posts: 8279
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Instead of OAuth 2.0 use Service account in google APIs
« Reply #8 on: September 20, 2020, 11:42:49 am »
What response did you receive?

andersonscinfo

  • Full Member
  • ***
  • Posts: 112
Re: Instead of OAuth 2.0 use Service account in google APIs
« Reply #9 on: September 20, 2020, 12:34:19 pm »
now i'm getting this message.
Code: Pascal  [Select][+][-]
  1. Invalid JWT Signature

ASBzone

  • Sr. Member
  • ****
  • Posts: 479
  • Automation leads to relaxation...
    • Free Console Utilities for Windows from BrainWaveCC
Re: Instead of OAuth 2.0 use Service account in google APIs
« Reply #10 on: September 20, 2020, 08:15:31 pm »
now i'm getting this message.
Code: Pascal  [Select][+][-]
  1. Invalid JWT Signature
Right 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".
-ASB: https://www.BrainWaveCC.com

Lazarus v2.0.11 r64032 / FPC v3.2.1-r47152 (via FpcUpDeluxe) -- Windows 64-bit install w/32-bit cross-compile
Primary System: Windows 10 Pro x64, Version 2009 (Build 19042)
Other Systems: Windows 10 Pro x64, Version 2004 (Build 19041) or greater

andersonscinfo

  • Full Member
  • ***
  • Posts: 112
Re: Instead of OAuth 2.0 use Service account in google APIs
« Reply #11 on: September 20, 2020, 10:57:19 pm »
now i'm getting this message.
Code: Pascal  [Select][+][-]
  1. Invalid JWT Signature
Right 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

  • Jr. Member
  • **
  • Posts: 71
Re: Instead of OAuth 2.0 use Service account in google APIs
« Reply #12 on: October 20, 2020, 11:00:51 pm »
Does 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

  • Full Member
  • ***
  • Posts: 104
    • Fano Framework, Free Pascal web application framework
Re: Instead of OAuth 2.0 use Service account in google APIs
« Reply #13 on: October 21, 2020, 12:32:19 am »
I'm not using google API

code
Code: Pascal  [Select][+][-]
  1. program project1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   {$IFDEF UNIX}
  7.   cthreads,
  8.   {$ENDIF}
  9.   Classes,
  10.   sysutils,
  11.   DateUtils,
  12.   fphttpclient,
  13.   opensslsockets,
  14.   Basic_Api, unit1;
  15.  
  16.  
  17. function TokenHeader: string;
  18. begin
  19.   Result := TJSONObject.New()
  20.     .Put('alg', 'RS256')
  21.     .Put('typ', 'JWT')
  22.     .Put('kid', '45d4f54ad5fa5df45asdfadsfqregthtg454878798')
  23.     .Stringify();
  24. end;
  25.  
  26. function TokenSign(const APrivateKey, APayload: string): string;
  27. var
  28.   VHeader: string;
  29.   VPayload: string;
  30.   VSignature: string;
  31. begin
  32.   VHeader := TokenHeader.EncodeBase64URL;
  33.   VPayload := APayload.EncodeBase64URL;
  34.   VSignature := (VHeader + '.' + VPayload).HMACSHA256(APrivateKey).EncodeBase64URL;
  35.   Result := VHeader + '.' + VPayload + '.' + VSignature;
  36. end;
  37.  
  38. function TokenPayload(const VJSON: IJSONValue): string;
  39. var
  40.   VDate: TDateTime;
  41. begin
  42.   VDate := Now;
  43.   Result := TJSONObject.New()
  44.     .Put('iss', VJSON.Path('client_email', ''))
  45.     .Put('aud', 'https://accounts.google.com/o/oauth2/token')
  46.     .Put('iat', IntToStr(DateTimeToUnix(VDate, False)))
  47.     .Put('exp', IntToStr(DateTimeToUnix(VDate.IncreaseMinutes(30), False)))
  48.     .Stringify()
  49. end;
  50.  
  51. var
  52.   VJSON: IJSONValue;
  53.   VPayload: string;
  54.   VToken: string;
  55.   VHttp: TFPHTTPClient;
  56.   VBody: TStrings;
  57.   VUrl: string;
  58.   VResponse: TStringStream;
  59. begin
  60.   VJSON := TJSONParser.New('agente-sc-nv9d-46509c843848.json', fmOpenReadWrite).Parse;  
  61.   VPayload := TokenPayload(VJSON);
  62.   VToken:= TokenSign(VJSON.Path('private_key', ''), VPayload);
  63.  
  64.  
  65.                                      
  66.   VHttp := TFPHTTPClient.Create(nil);
  67.   VBody := TStringList.Create;  
  68.   VResponse := TStringStream.Create('');
  69.   try
  70.     try
  71.       VBody.AddPair('grant_type', 'urn:ietf:params:oauth:grant-type:jwt-bearer');
  72.       VBody.AddPair('assertion', VToken);
  73.  
  74.       VUrl := 'https://accounts.google.com/o/oauth2/token';
  75.                                            
  76.       VHttp.FormPost(VUrl, VBody, VResponse);
  77.  
  78.       WriteLn(VResponse.DataString);
  79.       WriteLn('');
  80.  
  81.     except
  82.       raise
  83.     end;
  84.   finally
  85.     FreeAndNil(VResponse);
  86.     FreeAndNil(VBody);
  87.     FreeAndNil(VHttp);
  88.   end;
  89.  
  90.  
  91. end.
  92.  

you sign JWT with HMAC SHA 256 but set alg to RS256. It should be HS256. Read https.jwt.io for more information.
Fano Framework, Free Pascal web application framework https://fanoframework.github.io
Personal Projects https://v3.juhara.com
Github https://github.com/zamronypj

 

TinyPortal © 2005-2018