3

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)

Community
  • 1
  • 1
Daniele
  • 143
  • 1
  • 14
  • 1
    By "Google Play API" do you mean "Google Play Android Developer API"? Did you ever figure this out? I am using Java so it's a bit different, but I am having trouble using a Service Account instead of the recommended Web Application account... The access token that I get from the web service flow seems to have a different format than the access token should have, following the web application flow... – Kalina Sep 25 '12 at 18:56

0 Answers0