Task
Store last account activity information in database.
Realization
There are several ways to listen events related to session in Spring Security by implementing some of these listeners:
- javax.servlet.http.SessionAttributesListener
- javax.servlet.http.HttpSessionListener
- org.springframework.context.ApplicationListener
I found information, that the best way is to use Spring Application Listener
Don't use a HttpSessionListener for this as there is no garantuee that Spring Security will intiate the session creation or maybe even worse it destroys and creates a session (depending on your session strategy). [1]
It's possible to track many different useful application events with implemented custom Application Listener. For instance,
AuthorizationFailureEvent,
AuthenticationCredentialsNotFoundEvent or
AuthenticationSuccessEvent [2].
Adding successful login event listener and logout/session timeout event listener
Problem:
newly created session is replaced by a new one with copied data
By default, in all type of listeners, after user logged in, newly created session is replaced by a new one with copied data. This is because Spring Security automatically protects against Session Fixation Attack [3]. SessionFixationProtectionStrategy re-creates new session by calling onAuthentication method. SessionFixationProtectionStrategy performs it after authentication with success, copy all attributes from session, invalidate the session, next create a new session and write into the session the attributes [4].
Solution
- To get actual session id, it's possible to override the behaviour of org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy
- Turn off Session Fixation Attack protection by changing <session-fixation-protection> attribute on <session-management> in security configuration
I have chosen second solution
So I will have chance to check session fixation attack on my project. More about this attack: https://www.owasp.org/index.php/Session_fixation