spring-projects / spring-projects/spring-security
Property expiredUrl of SessionManagement is not handled correctly
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 9.6k
- Forks
- 6.3k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 52
Description
Spring Boot Security
Property expiredUrl of SessionManagement is not handled correctly
Actual Behavior
This situation is verified by having the limit of max 1 sessions for user in security config. Then signing in with the first user (A) and then logging in with the second user (B), the first one (A) is being invalidated on the server side correctly. When the first user (A) refreshes the page, instead of too many sessions per user error message, Spring security returns Invalid Session error code.
Detailed procedure is described below:
For cocurrent session, in this case expiredUrl not work, this is my use case:
- Open the first tab/browser and sign in
- Open the second tab/browser and sign in
- Go to the first tab/browser and refresh the page(F5) and redirect to invalidSessionUrl. KO
On step #3 spring will return invalidSessionUrl error message instead of too many sessions per user.
In order to avoid the session being shared, I reccomend to use two different browsers or a browser in incognito mode.
Note: The third step must be performed before the session timeout otherwise the session will be invalidated by timeout instead of concurrent session.
For testing, in demo project the session expiration is configured to 20 seconds.
Expected Behavior
- Open first browser = go to login page, insert credential and go home page.
- Open second browser = go to login page, insert credential and go home page.
- Go to first browser and press refresh page(F5) and redirect to expiredUrl. (Redirect to invalidSessionUrl only if session expired)
Configuration
.sessionManagement()
.sessionFixation().migrateSession()
.invalidSessionUrl(LOGIN_INVALID_SESSION_URL)
.maximumSessions(1)
.maxSessionsPreventsLogin(false)
.expiredUrl(LOGIN_EXPIRED_URL)
WorkAround
Add custom filter customConcurrentSessionFilter before ConcurrentSessionFilter.
http.addFilterBefore(customConcurrentSessionFilter(), ConcurrentSessionFilter.class)
Remove expiredUrl from default configuration because it is already declared into the custom filter
.sessionManagement()
.sessionFixation().migrateSession()
.invalidSessionUrl(LOGIN_INVALID_SESSION_URL)
.maximumSessions(1)
.maxSessionsPreventsLogin(false)
//.expiredUrl(LOGIN_EXPIRED_URL) <-- Note on commented instruction
Custom filter is almost identical to the ConcurrentSessionFilter, except in doFilter(...) before sending the redirect, creating new empty session.
By doing this, when the SessionManagementFilter is invoked, it does not handle InvalidSession error.
Version
Spring boot 1.4.2.RELEASE
Sample
https://github.com/MassimoScattarella/FixConcurrentSessionForSpringBootSecurity
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the behavior using the linked FixConcurrentSessionForSpringBootSecurity sample and its three-step session configuration. Start by reading ConcurrentSessionFilter and SessionManagementFilter, then trace how expiredUrl and invalidSessionUrl are selected. Done means a concurrently invalidated session redirects to expiredUrl, while a genuinely timed-out session still redirects to invalidSessionUrl.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring, spring-boot
- Domain
- authentication, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100