我需要使用 Google Play api 服务。我尝试使用“服务帐户”身份验证方法获取授权令牌,但我总是得到“400 Bad request”作为响应和 json:“error”:“invalid_grant”。
有没有人使用这种授权方法,Google Play Api 作为范围,C# 作为编程语言?
我到处搜索以通过现有库或我自己按照本指南(https://developers.google.com/accounts/docs/OAuth2ServiceAccount#libraries)和其他用户的建议来实现它,但它不起作用
这是代码
// 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;
以及此处指定的编码为 base 64 的方法:Utils.Base64Encode()
然后我在下面调用命令,我得到 {"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
(为简洁起见减少了编码的 JWT)