Tôi đang cố gắng liên lạc với API BigQuery được bật của ứng dụng thông qua phương thức máy chủ đến máy chủ.Yêu cầu mã thông báo truy cập tài khoản dịch vụ Google OAuth2 đưa ra yêu cầu 'Yêu cầu không hợp lệ'
Tôi đã chọn tất cả các hộp trên số Google guide này để xây dựng JWT của tôi là tốt nhất có thể trong C#.
Và tôi đã Base64Url mã hóa mọi thứ cần thiết.
Tuy nhiên, phản ứng duy nhất tôi nhận được từ google là 400 Bad Request
"error" : "invalid_request"
Tôi đã thực hiện chắc chắn về tất cả những điều sau đây từ những SO câu hỏi khác:
- The signature is properly encrypted using RSA and SHA256
- I am using POST and using application/x-www-form-urlencoded content type
- Escaped all the backslashes in the claim set
- Tried various grant_type and assertion values in the POST data
Tôi nhận được kết quả tương tự khi tôi sử dụng Fiddler. Các thông báo lỗi là bực bội thiếu chi tiết! Tôi có thể thử cái gì nữa ?! Đây là mã của tôi:
class Program
{
static void Main(string[] args)
{
// certificate
var certificate = new X509Certificate2(@"<Path to my certificate>.p12", "notasecret");
// header
var header = new { typ = "JWT", alg = "RS256" };
// claimset
var times = GetExpiryAndIssueDate();
var claimset = new
{
iss = "<email address of the client id of my app>",
scope = "https://www.googleapis.com/auth/bigquery",
aud = "https://accounts.google.com/o/oauth2/token",
iat = times[0],
exp = times[1],
};
// encoded header
var headerSerialized = JsonConvert.SerializeObject(header);
var headerBytes = Encoding.UTF8.GetBytes(headerSerialized);
var headerEncoded = Base64UrlEncode(headerBytes);
// encoded claimset
var claimsetSerialized = JsonConvert.SerializeObject(claimset);
var claimsetBytes = Encoding.UTF8.GetBytes(claimsetSerialized);
var claimsetEncoded = Base64UrlEncode(claimsetBytes);
// input
var input = headerEncoded + "." + claimsetEncoded;
var inputBytes = Encoding.UTF8.GetBytes(input);
// signiture
var rsa = certificate.PrivateKey as RSACryptoServiceProvider;
var cspParam = new CspParameters
{
KeyContainerName = rsa.CspKeyContainerInfo.KeyContainerName,
KeyNumber = rsa.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2
};
var aescsp = new RSACryptoServiceProvider(cspParam) { PersistKeyInCsp = false };
var signatureBytes = aescsp.SignData(inputBytes, "SHA256");
var signatureEncoded = Base64UrlEncode(signatureBytes);
// jwt
var jwt = headerEncoded + "." + claimsetEncoded + "." + signatureEncoded;
Console.WriteLine(jwt);
var client = new HttpClient();
var uri = "https://accounts.google.com/o/oauth2/token";
var post = new Dictionary<string, string>
{
{"assertion", jwt},
{"grant_type", "urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer"}
};
var content = new FormUrlEncodedContent(post);
var result = client.PostAsync(uri, content).Result;
Console.WriteLine(result);
Console.WriteLine(result.Content.ReadAsStringAsync().Result);
Console.ReadLine();
}
private static int[] GetExpiryAndIssueDate()
{
var utc0 = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var issueTime = DateTime.Now;
var iat = (int)issueTime.Subtract(utc0).TotalSeconds;
var exp = (int)issueTime.AddMinutes(55).Subtract(utc0).TotalSeconds;
return new[]{iat, exp};
}
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;
}
}
Tôi không tìm thấy bất kỳ điều gì rõ ràng, và tôi đã từng bước qua từng dòng mã của bạn. Một điều có thể là bạn đang mã hóa loại trợ cấp trong từ điển của bạn và FormUrlEncodededContent có thể kết thúc mã hóa kép. Vì vậy, tôi sẽ thử "urn: ietf: params: oauth: grant-type: jwt-bearer" để thay thế. –
Hình như HttpClient là từ một bản phát hành .NET framework gần đây, vì vậy tôi cài đặt nó và thử mã trực tiếp. Tôi cũng đã liên hệ nội bộ với một vài người có thể giúp đỡ. –