Reputation: 1175
In my Spring Boot application I add the user name as a custom session attribute. I did this so in the Tomcat manager I can see who is currently using the app:
I implemented javax.servlet.Filter to add the user name. But is this the recommended way to do that? After all, the attribute gets added on every single request. Does Spring provide a callback which is executed only once per session?
Upvotes: 1
Views: 2185
Reputation: 10650
I wondered this too.
What's the Spring-way to add session attributes (specifically related to Spring Security authentication)?
In my case, I registered a bean listening for Spring Security's InteractiveAuthenticationSuccessEvent
and SessionDestroyedEvent
events. These events fire without any explicit configuration in a default Spring Boot environment.
See https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#web.security:
The basic features you get by default in a web application are:
- . . .
- A DefaultAuthenticationEventPublisher for publishing authentication events.
This way I could add "username" as a session attribute immediately after a user logons and remove that attribute when the security session (security context) is destroyed:
@Component
public class SessionStoreUsernameAuthEventHandler {
@EventListener
public void audit(InteractiveAuthenticationSuccessEvent e) {
getSession().ifPresent(s -> s.setAttribute("username", e.getAuthentication().getName()));
}
@EventListener
public void audit(SessionDestroyedEvent e) {
getSession().ifPresent(s -> s.removeAttribute("username"));
}
private static Optional<HttpServletRequest> getCurrentRequest() {
return Optional.ofNullable(RequestContextHolder.getRequestAttributes())
.filter(ServletRequestAttributes.class::isInstance)
.map(ServletRequestAttributes.class::cast)
.map(ServletRequestAttributes::getRequest);
}
private static Optional<HttpSession> getSession() {
return getCurrentRequest().map(HttpServletRequest::getSession);
}
}
Upvotes: 0
Reputation: 90447
Once you add an attribute to HttpSession
, that attribute will keep existing in the session provided that the session does not expiry or you do not remove it from the session. So I don't see the point of implementing a Filter
to add an attribute to the HttpSession
for every request as this attribute is already exist in the session since you add it.
Besides , what you are doing is already done by Spring Security (p.s. in the SecurityContextPersistenceFilter
) and I would not do it one more time by myself. Actually that session attribute SPRING_SECURITY_CONTEXT
is the same object as we use SecurityContextHolder.getContext()
to access the current login user information.
That means if the Authentication
object that is set into the SecurityContextHolder
has its toString()
implemented to print the username (such as this), you could also see the username in the SPRING_SECURITY_CONTEXT
session attribute in Tomcat Manager.
Upvotes: 1
Reputation: 141
Spring MVC has tools for dealing with sessions and the @SessionAttributes section of this tutorial actually discusses registering a bean with Session scope so that it is called for each new session.
Upvotes: 0