I'm using Tomcat 6.0.32, Spring Security 3.0.5
In my web app some users have the ability to change other users privileges. When this happens I would like to invalidate any session for the user whose privileges were changed. Is this possible and if so how?
You can't usually invalidate a user session(s) immediately you change their account information without resorting to a container specific API, since the only way to access the HttpSession
is through the HttpServletRequest
object.
Instead you can cache the username in an in-memory store and consult it either in a filter or a custom AccessDecisionVoter
. Using a flag in the user table isn't really a great idea, since the flag is transient in nature (it is irrelevant after a server restart) and it's better to avoid the performance hit of a database query on every request.
There's a blog article on using custom voters for this kind of thing. It's out of date but the general approach is sound.
Another approach is to use Spring Security's SessionRegistry
which is part of the session-management functionality. Normally this is used to limit the number of sessions a user can have but can also be used to list currently authenticated users or mark their session for expiry.
It might also be an idea to just reload the user's privileges, rather than logging them out completely.
I believe this is what you need - get a list of logged in users and invalidate the sessions of those you don't need.
http://static.springsource.org/spring-security/site/docs/3.1.x/reference/session-mgmt.html#list-authenticated-principals
Assuming you are running your app on multiple servers you are going to need to have a way to make this happen on all the servers.
Add a timestamp field to your user table (or equivalent) that is updated when a user prvis are changed.
Write a servlet filter that checks if the current session is authenticated AND the timestamp for the user in the DB is greater than the session's creation time. If so invalidate the session and redirect somewhere.
This filter will need to come after the Spring Security filter.
If you are not running your app on multiple servers then you can use SessionRegistry.
The HTTPSession Object has an invalidate method. When a user changes some permissions you would need to call this method to invalidate and reload them for the current session.