我从帖子中复制了代码:
Google OAuth2 服务帐户访问令牌请求给出“无效请求”响应
并试图让我自己的 OAuth2.0 / JWT 身份验证工作。但无论我尝试做什么,我都会不断收到异常
System.Exception:远程服务器返回错误:(400)错误请求。
这是我的代码:
public void Authenticate()
{
string clientId = "...apps.googleusercontent.com";
string clientSecret = "...";
string emailAddress = "...@developer.gserviceaccount.com";
string publicKeyFingerprints = "...";
string certificateFilename = "Google Analytics - OAuth 2.0 - ...-privatekey.p12";
// certificate
var certificate = new X509Certificate2(certificateFilename, clientSecret);
// header
var header = new { typ = "JWT", alg = "RS256" };
// claimset
var times = GetExpiryAndIssueDate();
var claimset = new
{
iss = emailAddress,
scope = "https://www.googleapis.com/auth/analytics.readonly",
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;
_logger.DebugFormat("JWT: {0}", jwt);
var r = WebRequest.Create("https://accounts.google.com/o/oauth2/token") as HttpWebRequest;
r.Method = "POST";
r.ContentType = "application/x-www-form-urlencoded";
var post = string.Format("{0}={1}&{2}={3}",
"grant_type", HttpUtility.UrlEncode("urn:ietf:params:oauth:grant-type:jwt-bearer", Encoding.UTF8),
"assertion" , jwt);
var result = SendHttpRequest(r, post);
_logger.Debug(result);
}
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;
}
private string SendHttpRequest(HttpWebRequest request, string json)
{
string result = string.Empty;
try
{
_logger.DebugFormat("HttpRequest: {0} {1}", request.Method, request.RequestUri);
foreach (string header in request.Headers)
{
_logger.DebugFormat("Header[{0}]: {1}", header, request.Headers[header]);
}
_logger.DebugFormat("Body: {0}", json);
byte[] body = Encoding.UTF8.GetBytes(json);
request.ContentLength = body.Length;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(body, 0, body.Length);
}
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
using (Stream receiveStream = response.GetResponseStream())
{
using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8))
{
result = readStream.ReadToEnd();
}
}
_logger.DebugFormat("...done, result={0}", result);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
return result;
}
有谁知道这段代码有什么问题?