From c910ff2fc56b1dae8e4ff06f05b082df03265ed4 Mon Sep 17 00:00:00 2001 From: dmolinari Date: Tue, 14 Apr 2026 13:28:20 -0300 Subject: [PATCH] feat(infra): implement GetPrincipalFromExpiredToken in JwtService --- .../Security/JwtService.cs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/api/SIGCM2.Infrastructure/Security/JwtService.cs b/src/api/SIGCM2.Infrastructure/Security/JwtService.cs index 6af7842..02ac8c7 100644 --- a/src/api/SIGCM2.Infrastructure/Security/JwtService.cs +++ b/src/api/SIGCM2.Infrastructure/Security/JwtService.cs @@ -19,6 +19,31 @@ public sealed class JwtService : IJwtService _options = options; } + /// + public ClaimsPrincipal GetPrincipalFromExpiredToken(string accessToken) + { + var parameters = new TokenValidationParameters + { + ValidateIssuer = true, + ValidIssuer = _options.Issuer, + ValidateAudience = true, + ValidAudience = _options.Audience, + ValidateIssuerSigningKey = true, + IssuerSigningKey = new RsaSecurityKey(_rsa), + ValidateLifetime = false, // Key: accept expired tokens in refresh flow + ClockSkew = TimeSpan.Zero, + }; + + var handler = new JwtSecurityTokenHandler(); + var principal = handler.ValidateToken(accessToken, parameters, out var securityToken); + + if (securityToken is not JwtSecurityToken jwt || + !jwt.Header.Alg.Equals(SecurityAlgorithms.RsaSha256, StringComparison.OrdinalIgnoreCase)) + throw new SecurityTokenException("Invalid token algorithm"); + + return principal; + } + public string GenerateAccessToken(Usuario usuario) { var signingKey = new RsaSecurityKey(_rsa);