I need to use Google Play api service. I try to get the authorization token using "Service Account" authentication method but I always get "400 Bad request" as response and the json: "error": "invalid_grant".
Is there someone that is using this authorization method with Google Play Api as scope and C# as programming language?
I searched everywhere for implementing it by existing libraries or by myself following this guide (https://developers.google.com/accounts/docs/OAuth2ServiceAccount#libraries) and other users suggestions but it doesn't work
Here is the code
// HEADER
Dictionary<string, string> JWTHeaderObject = new Dictionary<string, string>();
JWTHeaderObject.Add("alg", "RS256");
JWTHeaderObject.Add("typ", "JWT");
string JWTHeader = JsonConvert.SerializeObject(JWTHeaderObject);
Dictionary<string, object> JWTContentObject = new Dictionary<string, object>();
JWTContentObject.Add("iss", ".....@developer.gserviceaccount.com");
JWTContentObject.Add("scope", "https:\\/\\/www.googleapis.com\\/auth\\/androidpublisher");
JWTContentObject.Add("aud", "https:\\/\\/accounts.google.com\\/o\\/oauth2\\/token");
DateTime now = DateTime.UtcNow;
// set to maximum expiration time: 1h from now
DateTime expireDate = now.Add(new TimeSpan(0, 55, 0));
// to UNIX timestamp
JWTContentObject.Add("exp", (int)Utils.ConverDateTimeToUnixTimestamp(expireDate));
JWTContentObject.Add("iat", (int)Utils.ConverDateTimeToUnixTimestamp(now));
string JWTContent = JsonConvert.SerializeObject(JWTContentObject);
string JWTBase64Header = Utils.Base64Encode(Encoding.UTF8.GetBytes(JWTHeader));
string JWTBase64Content = Utils.Base64Encode(Encoding.UTF8.GetBytes(JWTContent));
// create JWT signature with encoded header and content and the private key obtained from API console
byte[] JWTSignatureInput = Encoding.UTF8.GetBytes(JWTBase64Header + "." + JWTBase64Content);
X509Certificate2 cert = (X509Certificate2)Utils.GetCertificate(StoreName.My, StoreLocation.CurrentUser, "thumbprint");
RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey;
// without these two lines I get invalid algorithm on SHA256
// (see: http://blogs.msdn.com/b/shawnfa/archive/2008/08/25/using-rsacryptoserviceprovider-for-rsa-sha256-signatures.aspx)
RSACryptoServiceProvider rsaClear = new RSACryptoServiceProvider();
// Export RSA parameters from 'rsa' and import them into 'rsaClear'
rsaClear.ImportParameters(rsa.ExportParameters(true));
string JWTBase64Signature = Utils.Base64Encode(rsaClear.SignData(JWTSignatureInput, CryptoConfig.CreateFromName("SHA256")));
return JWTBase64Header + "." + JWTBase64Content + "." + JWTBase64Signature;
and the method specified here to encode to base 64: Utils.Base64Encode()
Then I call command below and I get {"error":"invalid_grant"}:
curl -d 'grant_type=assertion&assertion_type=http%3a%2f%2foauth.net%2fgrant_type%2fjwt%2f1.0%2fbearer&assertion=eyJhbGciOiJSUzI1N---.eyJpc3MiOiIxIiwic2---.KJ-DtTtdp5oIKPWVNqN---' https://accounts.google.com/o/oauth2/token
(encoded JWT reduced for brevity)