From f64d0d760ab1ef3cd9d4c327ba55e51cb199e367 Mon Sep 17 00:00:00 2001 From: Oleksandr Bezdieniezhnykh Date: Mon, 11 May 2026 23:45:12 +0300 Subject: [PATCH] [AZ-487] fix: JWT factory + tests now pass on net8.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - JwtTokenFactory.Create: negative `lifetime` produced Expires < NotBefore which `JwtSecurityToken` rejects at construction time. Shift NotBefore behind Expires whenever the requested lifetime is non-positive so the expired-token fixture round-trips and lifetime validation can fire. - JwtTokenFactoryTests: validate against a handler with `MapInboundClaims = false` so assertions read the factory's own claim names ("sub", "email", "permissions") rather than the .NET-default remapped ClaimTypes.* aliases. These were latent — masked by the CS0104 build break fixed in 753be43. Co-authored-by: Cursor --- .../Authentication/JwtTokenFactoryTests.cs | 8 +++++--- SatelliteProvider.Tests/TestUtilities/JwtTokenFactory.cs | 7 ++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/SatelliteProvider.Tests/Authentication/JwtTokenFactoryTests.cs b/SatelliteProvider.Tests/Authentication/JwtTokenFactoryTests.cs index 591acfc..1acb43c 100644 --- a/SatelliteProvider.Tests/Authentication/JwtTokenFactoryTests.cs +++ b/SatelliteProvider.Tests/Authentication/JwtTokenFactoryTests.cs @@ -14,10 +14,12 @@ public class JwtTokenFactoryTests [Fact] public void Create_ProducesTokenValidatedByMatchingParameters() { - // Arrange + // Arrange — disable inbound claim remapping so the test asserts + // the factory's actual output ("sub", "email", ...) rather than + // the framework's ClaimTypes.* aliases. var token = JwtTokenFactory.Create(Secret, subject: "alice"); var parameters = BuildParameters(Secret); - var handler = new JwtSecurityTokenHandler(); + var handler = new JwtSecurityTokenHandler { MapInboundClaims = false }; // Act var principal = handler.ValidateToken(token, parameters, out var validatedToken); @@ -40,7 +42,7 @@ public class JwtTokenFactoryTests new Claim("permissions", "FL") }; var token = JwtTokenFactory.Create(Secret, extraClaims: claims); - var handler = new JwtSecurityTokenHandler(); + var handler = new JwtSecurityTokenHandler { MapInboundClaims = false }; // Act var principal = handler.ValidateToken(token, BuildParameters(Secret), out _); diff --git a/SatelliteProvider.Tests/TestUtilities/JwtTokenFactory.cs b/SatelliteProvider.Tests/TestUtilities/JwtTokenFactory.cs index 668f5e1..f1802c5 100644 --- a/SatelliteProvider.Tests/TestUtilities/JwtTokenFactory.cs +++ b/SatelliteProvider.Tests/TestUtilities/JwtTokenFactory.cs @@ -24,6 +24,11 @@ public static class JwtTokenFactory var now = DateTime.UtcNow; var expires = now.Add(lifetime ?? TimeSpan.FromHours(1)); + // JwtSecurityToken rejects Expires <= NotBefore. For negative + // lifetimes (expired-token test fixture) shift NotBefore behind + // Expires so the constructor accepts the token and lifetime + // validation can fire downstream. + var notBefore = expires <= now ? expires.AddMinutes(-5) : now; var claims = new List { @@ -40,7 +45,7 @@ public static class JwtTokenFactory issuer: null, audience: null, claims: claims, - notBefore: now, + notBefore: notBefore, expires: expires, signingCredentials: credentials);