You need to sign in to do that
Don't have an account?
Jitendra Rawat
Google Service Account
How to authenticate google service account for google adword api. By using this document.
https://developers.google.com/accounts/docs/OAuth2ServiceAccount
My code Is as following :
public class GoogleAdWordApi{
public Static String getAccessToken(){
String accesstoken = '';
String headerStr64 = EncodingUtil.base64Encode(Blob.valueOf('{"alg":"RS256","typ":"JWT"}'));
headerStr64 = headerStr64.split('=')[0];
String str = '{"iss":"965360208690-a6qbrksf61b5dl7punv126ntb5aspu93@developer.gserviceaccount.com",';
str += '"scope":"' + 'https://www.googleapis.com/auth/prediction' + '",';
str += '"aud":"' + 'https://accounts.google.com/o/oauth2/token' + '",';
str += '"exp":' + system.now().addminutes(30).gettime()/1000 + ',';
str += '"iat":'+system.now().gettime()/1000;
str += '}';
System.debug('@@@ str==>'+str);
String claim_set64 = EncodingUtil.base64Encode(Blob.valueOf(str));
claim_set64 = claim_set64.split('=')[0];
System.debug('@@ claim_set64==>'+claim_set64);
//make signature
String sigInputstr = headerStr64 + '.' + claim_set64 ;
Blob signInputByteData = Blob.valueOf(sigInputstr);
Blob signByteData = System.Crypto.signWithCertificate('RSA-SHA256',signInputByteData,'privatekey');
String sigStr64 = EncodingUtil.base64Encode(signByteData);
System.debug('@@@ sigStr64==>'+sigStr64);
sigStr64 = sigStr64.split('=')[0];
System.debug('@@@ sigStr64==>'+sigStr64);
String jwtStr = headerStr64 + '.' + claim_set64 + '.' + sigStr64;
System.debug('@@@ jwtStr==>'+jwtStr);
HttpRequest req = new HttpRequest();
req.setEndpoint('https://accounts.google.com/o/oauth2/token');
req.setMethod('POST');
req.setHeader('Host','accounts.google.com');
req.setHeader('Content-Type','application/x-www-form-urlencoded');
String body = 'grant_type='+ EncodingUtil.urlEncode('urn:ietf:params:oauth:grant-type:jwt-bearer','UTF-8');
body += '&assertion=' + jwtStr;
req.setBody(body);
System.debug('@@ body==>'+body);
Http http = new Http();
HTTPResponse res = http.send(req);
System.debug(res.getBody());
return accesstoken;
}
}
--------------------------
Please tell me what is going worng with it.
https://developers.google.com/accounts/docs/OAuth2ServiceAccount
My code Is as following :
public class GoogleAdWordApi{
public Static String getAccessToken(){
String accesstoken = '';
String headerStr64 = EncodingUtil.base64Encode(Blob.valueOf('{"alg":"RS256","typ":"JWT"}'));
headerStr64 = headerStr64.split('=')[0];
String str = '{"iss":"965360208690-a6qbrksf61b5dl7punv126ntb5aspu93@developer.gserviceaccount.com",';
str += '"scope":"' + 'https://www.googleapis.com/auth/prediction' + '",';
str += '"aud":"' + 'https://accounts.google.com/o/oauth2/token' + '",';
str += '"exp":' + system.now().addminutes(30).gettime()/1000 + ',';
str += '"iat":'+system.now().gettime()/1000;
str += '}';
System.debug('@@@ str==>'+str);
String claim_set64 = EncodingUtil.base64Encode(Blob.valueOf(str));
claim_set64 = claim_set64.split('=')[0];
System.debug('@@ claim_set64==>'+claim_set64);
//make signature
String sigInputstr = headerStr64 + '.' + claim_set64 ;
Blob signInputByteData = Blob.valueOf(sigInputstr);
Blob signByteData = System.Crypto.signWithCertificate('RSA-SHA256',signInputByteData,'privatekey');
String sigStr64 = EncodingUtil.base64Encode(signByteData);
System.debug('@@@ sigStr64==>'+sigStr64);
sigStr64 = sigStr64.split('=')[0];
System.debug('@@@ sigStr64==>'+sigStr64);
String jwtStr = headerStr64 + '.' + claim_set64 + '.' + sigStr64;
System.debug('@@@ jwtStr==>'+jwtStr);
HttpRequest req = new HttpRequest();
req.setEndpoint('https://accounts.google.com/o/oauth2/token');
req.setMethod('POST');
req.setHeader('Host','accounts.google.com');
req.setHeader('Content-Type','application/x-www-form-urlencoded');
String body = 'grant_type='+ EncodingUtil.urlEncode('urn:ietf:params:oauth:grant-type:jwt-bearer','UTF-8');
body += '&assertion=' + jwtStr;
req.setBody(body);
System.debug('@@ body==>'+body);
Http http = new Http();
HTTPResponse res = http.send(req);
System.debug(res.getBody());
return accesstoken;
}
}
--------------------------
Please tell me what is going worng with it.
All Answers
https://developers.google.com/accounts/docs/OAuth2ServiceAccount
Also, are you getting any error messages with theabove code?
//Creating the header string and encoding it to Base64
String Header = '{"alg":"RS256","typ":"JWT"}';
String Header_Encode = EncodingUtil.base64Encode(blob.valueof(Header));
System.Debug('Header_Encode ###############################'+Header_Encode);
//setting the assertion expiration time and Issuing time
long currentTime = datetime.now().getTime()/1000;
long expiryTime = datetime.now().addHours(1).getTime()/1000;
//Creating the Claimset string and encoding it to Base64
String claim_set = '{"iss":"SERVICE ACC MAIL EMAIL ID"';
claim_set += ',"scope":"https://www.googleapis.com/auth/analytics.readonly"';//I made call for analytics api
claim_set += ',"aud":"https://www.googleapis.com/oauth2/v3/token"';
claim_set += ',"exp":'+expiryTime;
claim_set += ',"iat":'+currentTime+'}';
System.Debug('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'+claim_set);
String claim_set_Encode = EncodingUtil.base64Encode(blob.valueof(claim_set));
System.Debug('claim_set_Encode%%%%%%%%%%%%%%%%%%%%%%%%%'+claim_set_Encode);
//Creating the input for Signing i.e HeaderEncode.CalimSetEncode
String Singature_Encode = Header_Encode+'.'+claim_set_Encode;
System.Debug('Singature_Encode@@@@@@@@@@@@@@@@'+Singature_Encode);
//Download JSON format Key from google service account and take the Private key by removing all '\n'
String key = 'MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAM5HGuvhQEYBCuvDoYxlkU6bIaBIokCTIpkpVo6JSQt8e8p8yjzdGqI51DxYdKIPuHxG/S8wAUdf7gOHNQR3w+BcSzpu9Jr6bzTQSn/XLVVi4oc7LwlGsL0J0yJT8by4labAmf+qPYESboTKzMhMENU4A5TbjLZOPZ0D4nu9cZu9AgMBAAECgYAUkNZISi7kS9pQ4zJKEx5HngPePR+gHItIheyRTXKw6HpXF9X593leTzGvyonmVnboPROlDr4x5YiPZX2Nsnsex4IawQC2VoCVNI+2sqlisfNQSOeXjlJABnuWJNCW1afX29NNrkZ2rTSzzvZlaryCf9sp+eT9aMNLruq6kYCmwQJBAOd10jkRHaEWKKeLMO5fzLRiAKn7/5Uh4lKiTqiYM6q6T8IWFvMimwl+PsScazmS2kCQQDkJcsijgaCNyEdWWRJaqtrvVLDW4l7imfbYut5HOSp48SaDjWFCcUgUfCbIMBOEmuvGgnCUXoYcjTpnAdkLyc1AkEA3j7zrHgSyypLvxSX10uFc27m1FCe0aH8mtH1vMjqtXyeKvaGH59qxRkcy4A/FDJn5G5O6VZtU4ril7IOFMbMgQJASMOdBApUHRfEIf4utBOnVJdvXAtHz/UWpqvn+hqy+1Q/kfrSKvowutwnZvKNItlRKumdDzK5RC64nYE8AkHfuQJBAMI8VjZteXDvHuNvn989kNeFmlGPwdogKgfNelRDslKCikdAARTTu76HtPyHWl5inDo54I+O+e8uOtg7zpmf76k\u003d';
//Decoding the Private Key to bytes
blob privateKey = EncodingUtil.base64Decode(key);
System.Debug('privateKey is &&&&&&&&&&&&&&&&'+Singature_Encode_Url);
//Replacing '=' Value with blank value
Singature_Encode = Singature_Encode.replaceAll('=','');
//URL encoding the sign string before signing
String Singature_Encode_Url = EncodingUtil.urlEncode(Singature_Encode,'UTF-8');
System.Debug('Singature_Encode_Url ^^^^^^^^^^^^^'+Singature_Encode_Url);
blob Signature_b = blob.valueof(Singature_Encode_Url);
String Sinatute_blob = EncodingUtil.base64Encode(Crypto.sign('RSA-SHA256', Signature_b , privateKey));
System.Debug('Sinatute_blob Is &&&&&&&&&&&&&&&&&&&&&&&&& '+Sinatute_blob);
Sinatute_blob = Sinatute_blob.replaceAll('+', '-');
Sinatute_blob = Sinatute_blob.replaceAll('/', '_');
Sinatute_blob = Sinatute_blob.replaceAll('=', '');
System.Debug('Final signature Is (((((((((((((((((((((((((('+Sinatute_blob);
//Creating the JWT by appending Signature encode and Signature
String JWT = Singature_Encode+'.'+Signature;
System.Debug('JWT IS ************************'+JWT);
//Making the HTTP req
http h = new Http();
Httprequest req = new HttpRequest();
req.setEndpoint('https://www.googleapis.com/oauth2/v3/token');
req.setMethod('POST');
req.setHeader('Content-Type','application/x-www-form-urlencoded');
string bodyrequest = '';
bodyrequest = 'grant_type='+EncodingUtil.urlEncode('urn:ietf:params:oauth:grant-type:jwt-bearer','UTF-8');
bodyrequest += '&assertion='+EncodingUtil.urlEncode('JWT','UTF-8');
System.debug('%%%%%%%%%%'+bodyrequest);
req.setBody(bodyrequest);
HttpResponse res = h.send(req);
system.debug('******' + res.getBody()) ;
this is my own implementation, started from @jhenny asnwer. I added two features:
1) You can load directly the json service account credentials instead of picking email/key from it
2) Access-Token is automatically renewed when 60 minutes are expired
I faced an issue when using generated jwt to request access token. I got below error:
{
"error": "invalid_grant",
"error_description": "Invalid JWT Signature."
}
I used the sample code above and only changed the client email, private key, and scope.
I also changed the aud to "https://oauth2.googleapis.com/token", which is from the .json file. As google document requires https://developers.google.com/identity/protocols/OAuth2ServiceAccount
Can anyone help?