fix: concurrent session logout not invalidating JWT on first system#412
Conversation
logOutUserFromConcurrentSession only cleaned up old-style Redis session keys but never added the displaced user's JWT to the denylist. Because JwtUserIdValidationFilter validates solely via JWT signature and the denylist, System 1's token remained valid and all APIs returned 200 after System 2 forced a concurrent login. The root serialization bug: redisTemplate value serializer is Jackson2JsonRedisSerializer<User>, so storing a plain String JTI caused a deserialization failure on retrieval. Fixed by using the existing StringRedisTemplate bean for the jti: key operations. Fix: - Store username->JTI mapping via StringRedisTemplate at login (both userAuthenticate and superUserAuthenticate) - On concurrent-session logout, retrieve the JTI, add it to the denylist, evict user_<id> from User cache, and clean up jti: key - Add getAccessTokenExpiration() to JwtUtil to supply the TTL Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|



📋 Description
JIRA ID:
AMM-2306
✅ Type of Change
ℹ️ Additional Information
logOutUserFromConcurrentSession only cleaned up old-style Redis session keys but never added the displaced user's JWT to the denylist. Because JwtUserIdValidationFilter validates solely via JWT signature and the denylist, System 1's token remained valid and all APIs returned 200 after System 2 forced a concurrent login.
The root serialization bug: redisTemplate value serializer is Jackson2JsonRedisSerializer, so storing a plain String JTI caused a deserialization failure on retrieval. Fixed by using the existing StringRedisTemplate bean for the jti: key operations.
Fix: