本文介紹了如何使用 System.IdentityModel.Tokens.Jwt 生成具有 Google OAuth2 兼容算法 RSA SHA-256 的 JWT?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
限時送ChatGPT賬號..
我正在嘗試創建一個 JWT 以使用 Google 文檔中所述的服務帳戶進行授權,使用 System.IdentityModel.Tokens.Jwt.我有以下代碼:
I'm trying to create a JWT to authorize with a service account as described in Google documentation using System.IdentityModel.Tokens.Jwt. I have the following code:
byte[] key = Convert.FromBase64String("...");
var certificate = new X509Certificate2(key, "notasecret");
DateTime now = DateTime.UtcNow;
TimeSpan span = now - UnixEpoch;
Claim[] claims =
{
new Claim("iss", "email@developer.gserviceaccount.com"),
new Claim("scope", "https://www.googleapis.com/auth/plus.me"),
new Claim("aud", "https://accounts.google.com/o/oauth2/token"),
new Claim("iat", span.TotalSeconds.ToString()),
new Claim("exp", span.Add(TimeSpan.FromHours(1)).TotalSeconds.ToString())
};
JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
var descriptor = new SecurityTokenDescriptor
{
SigningCredentials = new SigningCredentials(
new InMemorySymmetricSecurityKey(key),
"http://www.w3.org/2001/04/xmldsig-more#hmac-sha256",
"http://www.w3.org/2001/04/xmlenc#sha256"),
Subject = new ClaimsIdentity(claims)
};
JwtSecurityToken jwtSecurityToken = (JwtSecurityToken)handler.CreateToken(descriptor);
string json = handler.WriteToken(jwtSecurityToken);
哪個輸出:
{ "typ" : "JWT" , "alg" : "HS256" }
雖然 Google 明確聲明它支持 SHA-256:
While Google explicitly states it supports SHA-256:
服務帳號依賴于 RSA SHA-256 算法和 JWT 令牌格式
Service accounts rely on the RSA SHA-256 algorithm and the JWT token format
根據 wtSecurityTokenHandler.InboundAlgorithmMap:
RS256 => http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
HS256 => http://www.w3.org/2001/04/xmldsig-more#hmac-sha256
所以當我更改代碼時:
new SigningCredentials(
new InMemorySymmetricSecurityKey(key),
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
"http://www.w3.org/2001/04/xmlenc#sha256");
我遇到了一個異常:
System.InvalidOperationException: IDX10632: SymmetricSecurityKey.GetKeyedHashAlgorithm( 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256' ) threw an exception.
SymmetricSecurityKey: 'System.IdentityModel.Tokens.InMemorySymmetricSecurityKey'
SignatureAlgorithm: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256', check to make sure the SignatureAlgorithm is supported.
這是否意味著微軟不支持谷歌獨家支持的算法?
Does it mean Microsoft doesn't support the algorithm Google supports exclusively?
推薦答案
private static async Task<string> GetAuthorizationToken(GoogleAuthOptions authOptions)
{
string jwt = CreateJwt(authOptions);
var dic = new Dictionary<string, string>
{
{ "grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer" },
{ "assertion", jwt }
};
var content = new FormUrlEncodedContent(dic);
var httpClient = new HttpClient { BaseAddress = new Uri("https://accounts.google.com") };
var response = await httpClient.PostAsync("/o/oauth2/token", content);
response.EnsureSuccessStatusCode();
dynamic dyn = await response.Content.ReadAsAsync<dynamic>();
return dyn.access_token;
}
private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
private static string CreateJwt(GoogleAuthOptions authOptions)
{
var certificate = new X509Certificate2(Convert.FromBase64String(authOptions.CertificateKey), authOptions.CertificateSecret);
DateTime now = DateTime.UtcNow;
var claimset = new
{
iss = authOptions.Issuer,
scope = "https://www.googleapis.com/auth/plus.me",
aud = authOptions.Audience,
iat = ((int)now.Subtract(UnixEpoch).TotalSeconds).ToString(CultureInfo.InvariantCulture),
exp = ((int)now.AddMinutes(55).Subtract(UnixEpoch).TotalSeconds).ToString(CultureInfo.InvariantCulture)
};
// header
var header = new { typ = "JWT", alg = "RS256" };
// encoded header
var headerSerialized = JsonConvert.SerializeObject(header);
var headerBytes = Encoding.UTF8.GetBytes(headerSerialized);
var headerEncoded = TextEncodings.Base64Url.Encode(headerBytes);
// encoded claimset
var claimsetSerialized = JsonConvert.SerializeObject(claimset);
var claimsetBytes = Encoding.UTF8.GetBytes(claimsetSerialized);
var claimsetEncoded = TextEncodings.Base64Url.Encode(claimsetBytes);
// input
var input = String.Join(".", headerEncoded, claimsetEncoded);
var inputBytes = Encoding.UTF8.GetBytes(input);
// signiture
var rsa = (RSACryptoServiceProvider)certificate.PrivateKey;
var cspParam = new CspParameters
{
KeyContainerName = rsa.CspKeyContainerInfo.KeyContainerName,
KeyNumber = rsa.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2
};
var cryptoServiceProvider = new RSACryptoServiceProvider(cspParam) { PersistKeyInCsp = false };
var signatureBytes = cryptoServiceProvider.SignData(inputBytes, "SHA256");
var signatureEncoded = TextEncodings.Base64Url.Encode(signatureBytes);
// jwt
return String.Join(".", headerEncoded, claimsetEncoded, signatureEncoded);
}
這篇關于如何使用 System.IdentityModel.Tokens.Jwt 生成具有 Google OAuth2 兼容算法 RSA SHA-256 的 JWT?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!
【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!