You need to sign in to do that
Don't have an account?
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?