We have a scenario whereby we have a series of applications, all using spring-session (w/Redis) where a user can log in more than once to access different apps.
If an admin amends a user to add a new role (e.g. access to a new app) (a GrantedAuthority) we need that to be reflected in all the users active sessions.
The problem is, i think, that the SecurityContextHolder uses ThreadLocal storage for the SecurityContext (which in turn holds the GrantedAuthorities).
I've tried interacting with the session repository and using that to update the session info but because of the above TL storage it doesn't get reflected across the applications.
Is there a common pattern/strategy to propagate updates to role information in this way?
Thanks.
The simplest (and IMO preferred) solution would be to force your users to re-authenticate and therefore create a new
Authenticationwhich would then contain a freshGrantedAuthoritycollection. You can use Spring Session'sFindByIndexNameSessionRepositoryto obtain all sessions for a given user and then delete them. This will generateSessionDeletedEventwhich will propagate to all your apps (since they share the same Redis session store).If you must preserve active sessions things are more complicated. You can still use
FindByIndexNameSessionRepositoryto obtain all sessions for a given user, but then you need to extractSecurityContextfrom each session and update itsAuthenticationwith new authorities and make sure that is done on all apps that share the session store. To do that you'll need to disableeraseCredentialsAfterAuthenticationon yourProviderManagerso that you can re-create theAuthenticationwith new authorities (you need credentials from the originalAuthentication). To ensureSecurityContextis updated on all your apps you have to employ some sort of publish-subscribe mechanism in order to trigger the execution of that code.As you can see the first solution is much simpler, and more secure (since you don't need to disable
eraseCredentialsAfterAuthentication). It's also worth noting that second solution would be simpler if Spring Session supportedHttpSessionAttributeListener(see this ticket) since that would cover the publish-subscribe mechanism part.