I’m having the same issue as described in this github issue, but it was apparently resolved in 2022.
Essentially, the line Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); always returns null even though the user is logged in.
Using AuthenticationContext from a view class works fine. My method is in a service class.
private String getAuthenticatedUsername() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null) {
log.debug("No authentication object found in security context.");
return null;
}
log.debug("Authentication object found: {}", authentication);
if (!authentication.isAuthenticated()) {
log.debug("Authentication object is not authenticated.");
return null;
}
Object principal = authentication.getPrincipal();
log.debug("Authentication principal: {}", principal);
if (principal instanceof String) {
log.debug("Principal is a string, likely 'anonymousUser'.");
return null;
}
if (principal instanceof UserDetails) {
String username = ((UserDetails) principal).getUsername();
log.debug("Authenticated username: {}", username);
return username;
}
log.debug("Principal is not an instance of UserDetails.");
return null;
}
Oh, I see what you mean. I’m assuming that the service knows the state of the logged in user (application context?), but the service is responding to requests from anywhere.
Thanks, Marco! Your explanation about the request thread was really helpful. I now understand why SecurityContextHolder works fine in a controller but not in my service.
In my case, I’m using Spring AI, so there’s an AI layer between the Vaadin view and the service. I’ll pass the user information from the view to the AI, and then the AI will forward it to the service in its requests. Thanks again for clarifying this!
Sorry for late answer.
By request thread, I mean the thread that is currently processing an HTTP request.
In an application secured by Spring Security, the request goes through the Spring Security filter chain that is responsible for setting the SecurityContext.
However, by default, the SecurityContext is set per thread, so if your code is executing some task in another thread, you should propagate the context to be able to access it.