Multiple Apps, Same Session and Updating Roles

766 views Asked by At

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.

1

There are 1 answers

0
Vedran Pavic On

The simplest (and IMO preferred) solution would be to force your users to re-authenticate and therefore create a new Authentication which would then contain a fresh GrantedAuthority collection. You can use Spring Session's FindByIndexNameSessionRepository to obtain all sessions for a given user and then delete them. This will generate SessionDeletedEvent which 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 FindByIndexNameSessionRepository to obtain all sessions for a given user, but then you need to extract SecurityContext from each session and update its Authentication with new authorities and make sure that is done on all apps that share the session store. To do that you'll need to disable eraseCredentialsAfterAuthentication on your ProviderManager so that you can re-create the Authentication with new authorities (you need credentials from the original Authentication). To ensure SecurityContext is 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 supported HttpSessionAttributeListener (see this ticket) since that would cover the publish-subscribe mechanism part.