我读了https://developers.google.com/accounts/docs/OAuth2ServiceAccount的教程
并试图使用他们的例子,但不断收到400个坏请求。这是我的密码:
ClaimSet cs = new ClaimSet()
{
aud = "https://www.googleapis.com/oauth2/v3/token",
iss = "1070248278615-hoq0meaunarl9hj8t9klg4gqkohlme9u@developer.gserviceaccount.com",
exp = GetTime(DateTime.UtcNow.AddHours(1)).ToString(),
iat = GetTime(DateTime.UtcNow).ToString(),
scope = "https://www.googleapis.com/auth/freebase"
};
//get the signed JWT
var signedJwt = JsonWebToken.Encode(cs);
public static string Encode(object payload, JwtHashAlgorithm algorithm = JwtHashAlgorithm.RS256)
{
return Encode(payload, Encoding.UTF8.GetBytes(PrivateKey), algorithm);
}
public static string Encode(object payload, byte[] keyBytes, JwtHashAlgorithm algorithm)
{
var segments = new List<string>();
var header = new { alg = algorithm.ToString(), typ = "JWT" };
byte[] headerBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header, Formatting.None));
byte[] payloadBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload, Formatting.None));
segments.Add(Base64UrlEncode(headerBytes));
segments.Add(Base64UrlEncode(payloadBytes));
var stringToSign = string.Join(".", segments);
var bytesToSign = Encoding.UTF8.GetBytes(stringToSign);
byte[] signature = HashAlgorithms[algorithm](keyBytes, bytesToSign);
segments.Add(Base64UrlEncode(signature));
return string.Join(".", segments.ToArray());
}
using (var wb = new WebClient())
{
var url = "https://www.googleapis.com/oauth2/v3/token/";
wb.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
var data2 = new NameValueCollection();
data2["grant_type"] = "urn:ietf:params:oauth:grant-type:jwt-bearer";
data2["assertion"] = signedJwt;
var response2 = wb.UploadValues(url, "POST", data2);
}现在,在获得访问令牌之后,我尝试写到freebase:使用下面的教程,我看到我应该得到谓词:https://developers.google.com/accounts/docs/OAuth2ServiceAccount#creatinganaccount
var url = "https://www.googleapis.com/freebase/v1/mqlwrite";
wb.QueryString.Add("lang", "/lang/en");
wb.QueryString.Add("query", "%5B%7B%0A%20%20%22mid%22%3A%20%22%2Fm%2F011840dm%22%2C%0A%20%20%22%2Fcommon%2Ftopic%2Ftopic_equivalent_webpage%22%3A%20%7B%0A%20%20%20%20%22connect%22%3A%20%22insert%22%2C%0A%20%20%20%20%22value%22%3A%20%22http%3A%2F%2Fwww.imdb.com%2Fname%2Fnm4963898%2F%22%0A%20%20%7D%0A%7D%5D");
wb.Headers.Add("Authorization", "Bearer " + accesstoken);
var ResponseBytes = wb.DownloadString(url);感谢你的帮助:)
发布于 2014-12-29 16:00:34
您在POST数据中包含了Content-Type,但是它应该作为headers的一部分来显示,如下所示:
wb.Headers.Add("Content-Type","application/x-www-form-urlencoded");但是,除非重写,否则使用UploadValues将是默认设置。
除此之外,UploadValues将自动对您的值进行URL编码,因此您应该以它们的原始形式表示它们;因此对于授予类型,这意味着:
data2["grant_type"] = "urn:ietf:params:oauth:grant-type:jwt-bearer";Edit1:
另外,您的JWT使用错误的aud声明,因为它被设置为https://accounts.google.com/o/oauth2/token而不是https://www.googleapis.com/oauth2/v3/token,并且自2012年7月2日起过期。
Edit2:您还必须在没有尾随斜杠的情况下将iat和exp时间戳正确地贴到URL上。使用Newtonsoft.Json成功测试代码
public class GoogleServiceAccountBearerJWTSample
{
private static string Base64UrlEncode(byte[] input)
{
var output = Convert.ToBase64String(input);
output = output.Split('=')[0]; // Remove any trailing '='s
output = output.Replace('+', '-'); // 62nd char of encoding
output = output.Replace('/', '_'); // 63rd char of encoding
return output;
}
public static string Encode(object payload, AsymmetricAlgorithm rsa) {
var segments = new List<string>();
var header = new { alg = "RS256", typ = "JWT" };
byte[] headerBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(header, Formatting.None));
byte[] payloadBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(payload, Formatting.None));
segments.Add(Base64UrlEncode(headerBytes));
segments.Add(Base64UrlEncode(payloadBytes));
var stringToSign = string.Join(".", segments.ToArray());
var bytesToSign = Encoding.UTF8.GetBytes(stringToSign);
// VARIANT A - should work on non-SHA256 enabled systems
var rs = rsa as RSACryptoServiceProvider;
var cspParam = new CspParameters
{
KeyContainerName = rs.CspKeyContainerInfo.KeyContainerName,
KeyNumber = rs.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2
};
var aescsp = new RSACryptoServiceProvider(cspParam) { PersistKeyInCsp = false };
var signature = aescsp.SignData(bytesToSign, "SHA256");
// END OF VARIANT A
// VARIANT B - works on FIPS SHA256 enabled systems
// var pkcs1 = new RSAPKCS1SignatureFormatter(rsa);
// pkcs1.SetHashAlgorithm("SHA256");
// var signature = pkcs1.CreateSignature(new SHA256Managed().ComputeHash(bytesToSign));
// END OF VARIANT B
segments.Add(Base64UrlEncode(signature));
return string.Join(".", segments.ToArray());
}
public static void Main()
{
var utc0 = new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);
var issueTime = DateTime.UtcNow;
var iat = (int)issueTime.Subtract(utc0).TotalSeconds;
var exp = (int)issueTime.AddMinutes(55).Subtract(utc0).TotalSeconds; // Expiration time is up to 1 hour, but lets play on safe side
var payload = new {
iss = "xxxxxxxxxxxxxxxxxx@developer.gserviceaccount.com",
aud = "https://www.googleapis.com/oauth2/v3/token",
scope = "https://www.googleapis.com/auth/freebase",
exp = exp,
iat = iat
};
var certificate = new X509Certificate2("google-client.p12", "notasecret");
var signedJwt = Encode(payload, certificate.PrivateKey);
//System.Console.WriteLine(signedJwt);
using (var wb = new WebClient())
{
var url = "https://www.googleapis.com/oauth2/v3/token";
var data2 = new NameValueCollection();
data2["grant_type"] = "urn:ietf:params:oauth:grant-type:jwt-bearer";
data2["assertion"] = signedJwt;
var response2 = wb.UploadValues(url, "POST", data2);
System.Console.WriteLine(Encoding.UTF8.GetString(response2));
}
}
}https://stackoverflow.com/questions/27690595
复制相似问题