Last active
April 3, 2025 10:32
-
-
Save ddjerqq/d2c378e14f5b6f28ba8df2287547aee5 to your computer and use it in GitHub Desktop.
dotnet JWT generator using an RSA encrypted private key
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class JwtGenerator | |
{ | |
public const string TokenName = "authorization"; | |
public static readonly string ClaimsIssuer = "JWT__ISSUER".FromEnvRequired(); | |
public static readonly string ClaimsAudience = "JWT__AUDIENCE".FromEnvRequired(); | |
private static readonly string Key = "JWT__KEY".FromEnvRequired(); | |
private static readonly string KeyPath = "JWT__KEY_PATH".FromEnvRequired(); | |
/// <summary> | |
/// These events ensure we can read the authorization from cookies, auery or headers. <br/> | |
/// The priorities are: query > header > cookie.<br/> | |
/// </summary> | |
public static readonly JwtBearerEvents Events = new() | |
{ | |
OnMessageReceived = ctx => | |
{ | |
ctx.Request.Query.TryGetValue(TokenName, out var query); | |
ctx.Request.Headers.TryGetValue(TokenName, out var header); | |
ctx.Request.Cookies.TryGetValue(TokenName, out var cookie); | |
ctx.Token = (string?)query ?? (string?)header ?? cookie; | |
return Task.CompletedTask; | |
}, | |
}; | |
private static readonly JwtSecurityTokenHandler Handler = new(); | |
private static readonly SigningCredentials SigningCredentials; | |
public static readonly TokenValidationParameters TokenValidationParameters; | |
/// <summary> | |
/// Static constructor ensures that we load the key file and decrypt it using the provided env variables. | |
/// </summary> | |
static JwtGenerator() | |
{ | |
var key = RSA.Create(); | |
var keyBytes = File.ReadAllBytes(KeyPath); | |
key.ImportFromEncryptedPem(Encoding.UTF8.GetString(keyBytes), Encoding.UTF8.GetBytes(Key)); | |
var securityKey = new RsaSecurityKey(key); | |
SigningCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.RsaSha256Signature); | |
TokenValidationParameters = new TokenValidationParameters | |
{ | |
ValidIssuer = ClaimsIssuer, | |
ValidAudience = ClaimsAudience, | |
IssuerSigningKey = securityKey, | |
ValidateIssuer = true, | |
ValidateAudience = true, | |
ValidateLifetime = true, | |
ValidateIssuerSigningKey = true, | |
ValidAlgorithms = [SecurityAlgorithms.RsaSha256Signature], | |
}; | |
} | |
/// <summary> | |
/// Generates a JWT token with the provided claims and expiration time. | |
/// </summary> | |
public static string GenerateToken(IEnumerable<Claim> claims, TimeSpan expiration) | |
{ | |
var token = new JwtSecurityToken( | |
ClaimsIssuer, | |
ClaimsAudience, | |
claims, | |
expires: DateTime.UtcNow.Add(expiration), | |
signingCredentials: SigningCredentials); | |
return Handler.WriteToken(token); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class StringExt | |
{ | |
public static string FromEnvRequired(this string key) => | |
Environment.GetEnvironmentVariable(key) | |
?? throw new InvalidOperationException($"{key} is not set in the environment"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
.env.example