I have created a REST API that require a authentication with JWT.
My implementation is very similar with the code found on https://auth0.com/blog/securing-spring-boot-with-jwts/
When I try to return the current user, I always receive a null
return.
My code:
Websecurity:
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
// login
.antMatchers(HttpMethod.POST, "/login")
.permitAll()
.anyRequest()
.authenticated()
.and()
.addFilterBefore(new JWTLoginFilter(
"/login", authenticationManager(), logService), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
JWTAuthenticationFilter:
public class JWTAuthenticationFilter extends GenericFilterBean {
@Override
public void doFilter(
ServletRequest req,
ServletResponse res,
FilterChain filterChain) throws IOException, ServletException {
Authentication authentication = TokenAuthenticationService.getAuthentication((HttpServletRequest)req);
SecurityContextHolder.getContext().setAuthentication(authentication);
filterChain.doFilter(req, res);
}
}
I don't included all the code of JWT authentication, because JWT is working ok, user access too. I believe the problem is in the filter or some configuration.
Then, I made a facade
to get the current user on a service
or controller
, with the following code (method 4 on http://www.baeldung.com/get-user-in-spring-security):
public Authentication getAuthentication() {
return SecurityContextHolder.getContext().getAuthentication();
}
but this don't worked.
- SecurityContextHolder.getContext()
returned org.springframework.security.core.context.SecurityContextImpl@ffffffff: Null authentication
.
- SecurityContextHolder.getContext().getAuthentication()
returned null
object.
Update (and solution):
In my controller, if I use this code:
SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
I can get the current user, but, in my service, the exact same code don't work.
But then, I remember that SecurityContext
is "lost" on another thread (source: https://docs.spring.io/spring-security/site/docs/current/reference/html/concurrency.html), and my service is async
@Async
public CompletableFuture<Optional<ViewUserDto>> findByLogin(String login) throws InterruptedException {
...
}
So, using the code found here: https://stackoverflow.com/a/40347437/4794469, everything works correctly. I don't known if this can bring any side effects for my code yet (all unit tests worked)