From bce591e63c58ae673071e991dcabb38656cf7abc Mon Sep 17 00:00:00 2001 From: dmolinari Date: Wed, 15 Apr 2026 11:03:15 -0300 Subject: [PATCH] fix(auth): preserve JWT claim names in bearer middleware JwtBearerOptions.MapInboundClaims defaulted to true, which mapped the 'sub' claim to ClaimTypes.NameIdentifier in HttpContext.User. Logout endpoint read User.FindFirst("sub") and got null, returning 401 for any authenticated caller. Fix: set MapInboundClaims=false and pin NameClaimType="name" so the JWT claims land in the principal with their original names, aligning with how JwtService.GetPrincipalFromExpiredToken (used by refresh) already consumes them. Unblocks Login_Refresh_Logout_FullFlow integration test (15/15 green). --- src/api/SIGCM2.Infrastructure/DependencyInjection.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/api/SIGCM2.Infrastructure/DependencyInjection.cs b/src/api/SIGCM2.Infrastructure/DependencyInjection.cs index 4197ba5..0f91ae0 100644 --- a/src/api/SIGCM2.Infrastructure/DependencyInjection.cs +++ b/src/api/SIGCM2.Infrastructure/DependencyInjection.cs @@ -72,10 +72,13 @@ public static class DependencyInjection services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(); - // Post-configure JWT Bearer — wire RSA public key + validation params from resolved options + // Post-configure JWT Bearer — wire RSA public key + validation params from resolved options. + // MapInboundClaims=false: preserve JWT claim names as-is ("sub", "rol", etc.). + // Without this, the middleware maps "sub" → ClaimTypes.NameIdentifier and breaks User.FindFirst("sub"). services.AddOptions(JwtBearerDefaults.AuthenticationScheme) .PostConfigure((jwtBearerOpts, rsaKey, jwtOpts) => { + jwtBearerOpts.MapInboundClaims = false; jwtBearerOpts.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, @@ -86,7 +89,8 @@ public static class DependencyInjection ValidAudience = jwtOpts.Audience, ValidateLifetime = true, ClockSkew = TimeSpan.Zero, - RoleClaimType = "rol" + RoleClaimType = "rol", + NameClaimType = "name" }; });