fix: getSession(false) returns null after session invalidation (#115) - #116
Conversation
MockRequest.getSession(false) returned the stale, invalidated session
instead of null once the session had been invalidated, violating the
servlet container contract. This broke logout: Spring Security's
SecurityContextLogoutHandler invalidates the HttpSession and then calls
HttpSessionSecurityContextRepository.saveContext, which looks up
request.getSession(false). In a real container that returns null and the
empty-context save is a no-op, but the mock handed back the invalidated
MockHttpSession, so removing the security-context attribute threw
IllegalStateException("invalidated").
Honour the servlet contract: once invalidated, getSession(false) returns
null and getSession(true) creates a fresh session. Add LogoutTest
covering the issue #115 sequence plus the logout->redirect-to-login and
logout->new-login flows, and update MockRequestTest to assert the
corrected behaviour.
|
/format |
This comment has been minimized.
This comment has been minimized.
| Assertions.assertThrows(IllegalArgumentException.class, | ||
| () -> window.navigate(ProtectedView.class)); | ||
| Assertions.assertInstanceOf(LoginView.class, window.getCurrentView()); |
There was a problem hiding this comment.
There is weird behavior here: navigating on an existing window redirects to Login view, but if I create a new window, the protected page is accessible.
This might be acceptable, since user represents a logged-in user, but it is not intuitive. If we agree on keep this behavior, we should explicitly document it.
Or should the BrowserlessUserContext be closed on session invalidation?
Maybe this topic deserves a separate ticket.
There was a problem hiding this comment.
Which part do you find unintuitive?
There was a problem hiding this comment.
BrowserlessUserContext looks paired to a user session. It starts with a logged-in user, and all windows I create can navigate to protected views.
If I simulate a press to a logout button, the current window is then unable to navigate to protected pages and navigation is redirected to the login view.
But if I create a new window, that one is authenticated again, but not the old one.
So I have a user session that is half authenticated and half unauthenticated.
This looks confusing to me.
There was a problem hiding this comment.
Right, so the problem is that it should really invalidate the "user" object also so that all windows, both existing and new, are unauthenticated. That's how a real application would work if you log out in one tab.
There was a problem hiding this comment.
Yeah, that's what I would expect. If you need to log in again, you should create a new context (e.g. app.newUser("john", "USER")).
There was a problem hiding this comment.
I'll create a separated ticket to fix this issue
MockRequest.getSession(false) returned the stale, invalidated session instead of null once the session had been invalidated, violating the servlet container contract. This broke logout: Spring Security's SecurityContextLogoutHandler invalidates the HttpSession and then calls HttpSessionSecurityContextRepository.saveContext, which looks up request.getSession(false). In a real container that returns null and the empty-context save is a no-op, but the mock handed back the invalidated MockHttpSession, so removing the security-context attribute threw IllegalStateException("invalidated").
Honour the servlet contract: once invalidated, getSession(false) returns null and getSession(true) creates a fresh session. Add LogoutTest covering the issue #115 sequence plus the logout->redirect-to-login and logout->new-login flows, and update MockRequestTest to assert the corrected behaviour.
Fixes #115