I have been looking for a way to reload our Spring Security UserDetails object every request and cannot find an example anywhere.
Does anyone know how to do such a t
For the side of the admin user changing the other user's authority: You can try to retrieve the sessions of the affected user and set some attribute to indicate a reload is needed.
If you happen to use Spring Session with session attributes persisted in the database (e.g., to support multiple container instances), you can tag an active session for reload when the admin user makes changes to the authorities:
@Autowired
private FindByIndexNameSessionRepository sessionRepo;
public void tag(String username) {
Map sessions = sessionRepo.findByIndexNameAndIndexValue
(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, username);
for (Session s : sessions.values()) {
s.setAttribute("reloadAuth", true);
sessionRepo.save(s);
}
}
For the logged-in user side: You can write your Spring Security Filter that will check for the session attribute whether to reload the current session's authentication or not. If an admin has tagged it for reload, we retrieve again the Principal from the DB and re-set our Authentication.
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpSession session = ((HttpServletRequest) request).getSession();
if (session != null) {
Boolean reload = (Boolean) session.getAttribute("reloadAuth");
if (Boolean.TRUE.equals(shouldReloadRoles)) {
session.removeAttribute("reloadAuth");
/* Do some locking based on session ID if you want just to avoid multiple reloads for a session */
Authentication newAuth = ... // Load new authentication from DB
SecurityContextHolder.getContext().setAuthentication(newAuth);
}
}
chain.doFilter(request, response);
}