fix: validate token before HA distribution in doInvalidate — GH#4754#4757
fix: validate token before HA distribution in doInvalidate — GH#4754#4757balhar-jakub wants to merge 2 commits into
Conversation
- Fix 1: Move parseJwtToken() before peer distribution in doInvalidate() to reject invalid tokens immediately instead of distributing them first. Catches TokenNotValidException/TokenExpireException/TokenFormatNotValidException before any peer calls. Retains BadCredentialsException suppression for legitimate ZOSMF rejection after successful peer distribution. - Fix 2: Add null/empty guards at invalidateJwtToken() and invalidateJwtTokenGateway() entry points, throwing TokenNotProvidedException for defense-in-depth. - Fix 3: Add empty-value filter to HttpUtils.getCookieValue() to match ZAAS getTokenFromCookie() behavior, preventing empty cookies from reaching authentication service in modulith HA mode. - Tests: 7 new tests added (HttpUtilsTest + AuthenticationServiceTest), 2 existing tests fixed to use real JWT tokens for parse-before-distribute. All 46 AuthenticationService tests pass, all HttpUtils tests pass.
Architectural Review — #4754 (PR #4757)Verdict: APPROVED ✅ Design ComplianceThe implementation follows the recommended fix from the issue exactly:
Structural Integrity
API Contract
V4 Alignment
Test Coverage
Edge Cases
|
Empty token logout was not throwing ZaasClientException because:
1. ZaasClientImpl.logout('') delegates to ZaasJwtService.logout('')
2. logoutJwtToken('') sends cookie with empty value
3. Gateway's getTokenFromRequest filters out empty cookie values
4. flatMap never runs → Spring Security treats as success → 2xx
5. doLogoutRequest gets success → no exception thrown
Fix: add null/empty check in ZaasClientImpl.logout() matching the
pattern used by login(), query(), passTicket(), and validateOidc().
Added unit tests for null and empty token cases.
Architectural Review — PR #4757 (Rework Fix)Build: Rework SummaryThe original implementation failed CITestsModulith because
Fix Applied (commit 0d9e6f4)
Architectural AssessmentAPPROVED ✓ — No issues found. 1. Defense-in-depth layering ✓Three independent guard layers now protect against empty tokens:
2. Token validation ordering in
|
Architectural Review — PR #4757 (Rework Cycle 1 — Resolved)Previous status: CITestsModulith failed on Rework fix (commit 0d9e6f4): Added null/empty guard in Current CI status (PR #4757):
Build verification: Verdict: APPROVED ✅ — The fix resolves the CITestsModulith regression. All required CI checks pass. Proceeding to CI gate finalization and QA handoff. |
|
QA Review -- PR #4757 (Logout Empty Token in Modulith HA)Verdict: PASSED Acceptance Criteria Verification
Pavel's Lens -- All 8 Rules Checked
Tests Run
Non-Blocking Notes
SummaryClean fix addressing the root cause (validate-before-distribute) with defense-in-depth guards at all entry points. The rework cycle (CITestsModulith regression) was correctly resolved. All tests pass. Minor log ordering and redundant null check noted above -- both are non-blocking. |
Security Review — PR #4757 (Logout Empty Token in Modulith HA)Verdict: APPROVED ✅ — No security findings. Zero CRITICAL/HIGH/MEDIUM/LOW issues. Pavel's Lens — All 8 Rules Checked
Security Review — All 6 Categories
Key Security AssessmentThis fix is a security improvement:
SonarQubeQuality Gate: PASSED. 0 Security Hotspots. 96.2% Coverage on New Code. 0.0% Duplication on New Code. SummaryAPPROVED for merge. No security concerns. The two minor Pavel-lens notes (log ordering, redundant null check) are cosmetic and do not affect security posture. |



Fixes #4754 — Logout Accepts Empty Token in Modulith HA
Problem
In modulith HA, an empty token sent to the logout endpoint returns 204 No Content instead of an error. The root cause:
doInvalidate()attempted peer distribution first, settingisInvalidatedOnAnotherInstance=true, thenparseJwtToken("")threwBadCredentialsExceptionwhich was suppressed becauseisInvalidatedOnAnotherInstancewas true.Fix
Three changes across 4 files:
Restructured
doInvalidate()— movedparseJwtToken()to BEFORE peer distribution. Invalid tokens (empty, null, malformed) are rejected immediately withTokenNotValidException/TokenNotProvidedException. Thecatch(BadCredentialsException)block is retained for ZOSMF invalidation failures after successful token parsing and peer distribution.Null/empty guards at
invalidateJwtToken()andinvalidateJwtTokenGateway()entry points, throwingTokenNotProvidedException.Cookie filtering parity — added
.filter(value -> !value.isEmpty())to GatewayHttpUtils.getCookieValue()to match ZAASgetTokenFromCookie()behavior.Tests
(architect PR review to follow)