fix(auth): close same-ms revocation race + tidy audit cleanup
Bumps token_revoked_before by 1ms so a JWT issued in the same millisecond as a logout call (Date.from(Instant.now()) quantises iat to ms) does not survive the filter's strict isBefore check. Also extends LogoutControllerIT @AfterEach to delete the audit_log row, keeping reused Postgres containers clean for downstream ITs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -192,7 +192,11 @@ public class UiAuthController {
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
String userId = stripSubjectPrefix(authentication.getName());
|
||||
userRepository.revokeTokensBefore(userId, Instant.now());
|
||||
// +1ms guards against same-millisecond races: JWT iat is quantised to
|
||||
// milliseconds (Date.from(now) in JwtServiceImpl), and the filter check
|
||||
// is strict isBefore. Without the bump, a token issued in the same
|
||||
// millisecond as logout would survive revocation.
|
||||
userRepository.revokeTokensBefore(userId, Instant.now().plusMillis(1));
|
||||
auditService.log(userId, "logout", AuditCategory.AUTH, null, null,
|
||||
AuditResult.SUCCESS, httpRequest);
|
||||
log.info("UI user logged out: {}", userId);
|
||||
|
||||
@@ -30,6 +30,7 @@ class LogoutControllerIT extends AbstractPostgresIT {
|
||||
@AfterEach
|
||||
void cleanup() {
|
||||
userRepository.delete("logout-test");
|
||||
jdbc.update("DELETE FROM audit_log WHERE username = ?", "logout-test");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user