We are running into an issue with the Elytron security subsystem when web authentication is done using HttpServletRequest.login() calls. SSO sessions are being destroyed after the undertow idle session-timeout duration is hit even though sessions are still active/requests are being made. This behavior was not seen when using the legacy security subsystem.
Our web apps rely on servlet filters to authenticate requests where we make calls to HttpServletRequest.login(). Although SSO is working with programmatic authentication in that the sessions are reauthenticated properly, the call to DefaultSingleSignOnSession.put() is not made to update the SSO participants list. Each request has the proper JSESSIONIDSSO in the cookie header so https://issues.redhat.com/browse/ELY-1626 is not the issue. Without updating the SSO participants list, we are running into a bug where the undertow InMemorySessionManager timeout logic triggers a logout of the SSO session when it hits the idle session-timeout value (default of 30 minutes) even when the sessions are clearly not idle.
A simple setup to see that the SSO participants list is only updated on the first HttpServletRequest.login() request:
Both render properly and SSO worked but, you’ll find that there is only one instance in the log where the SSO participants list was updated and that was on the initial appA/login request. The log messages you’d look for are what’s being printed out in DefaultSingleSignOnSession.put()
This means that no matter what requests are made after that initial call, nothing is tied to that SSO session and will be terminated after the undertow session-timeout is hit.
When debugging the code, the initial HttpAuthenticator.login() request properly authenticates and updates the SSO participants list when it hits this line:
All other requests that go through that programmatic authentication setup, go through the restoreIdentity() call:
In there, the cachedIdentity is found since the first call added it to the ProgrammaticSingleSignOnCache properly. It is then imported to the new authenticationContext and authorized is set to true. Since it is authorized, the cache boolean remains false. The only time the DefaultSingleSignOnSession.put() call is made at this point is if cache was true:
HttpAuthenticator.restoreIdentity() then returns true and the request is good to go. The problem is that the SSO participants list was never updated to include the new session id.
While debugging, once we manually changed “cache” to equal true, the participants list was updated and the undertow idle session timeout was working properly.
Although turning off the undertow idle session-timeout (setting it to a value of -1) clears up this issue, this isn’t something we want to do in our large-scale project where the built-in session cleanup is important to keep, especially when it is only broken in this specific use case.
We couldn’t find a bug reported on this, so we want to know if our investigation is correct and that this is indeed the fix that’s needed for this use case?
Thanks