Issue
I am developing a simple REST service where registered users can post stuff.
Registration and authentication work fine, however, when I try sending POST
or GET
requests to any protected path, I see a 200 status code without anything in response body in Postman.
If needed, I can provide the whole source code, but I think the issue lies somewhere either in filter class or in the configuration class.
My configuration:
http
.csrf().disable()
.sessionManagement()
.sessionCreationPolicy(STATELESS)
.and()
.addFilterAfter(new JwtFilter(userService, jwtUtils), BasicAuthenticationFilter.class)
.authorizeRequests()
.antMatchers("/api/v1/register/**", "/api/v1/users/authenticate").permitAll()
.anyRequest().authenticated();
My JwtFilter
class:
@RequiredArgsConstructor
public class JwtFilter extends OncePerRequestFilter {
private final UserService userService;
private final JwtUtils jwtUtils;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain) throws ServletException, IOException {
var header = request.getHeader(HttpHeaders.AUTHORIZATION);
if (header == null || !header.startsWith(jwtUtils.Bearer)) {
chain.doFilter(request, response);
return;
}
var jwt = header.replace(jwtUtils.Bearer, "");
var username = jwtUtils.extractUsername(jwt);
if (username == null && SecurityContextHolder.getContext().getAuthentication() != null) {
chain.doFilter(request, response);
return;
}
var user = userService.loadUserByUsername(username);
if (!jwtUtils.validateToken(jwt, user) || !user.isEnabled()) {
chain.doFilter(request, response);
return;
}
var passwordAuthToken = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
passwordAuthToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); // implies that request should contain user details?
SecurityContextHolder.getContext().setAuthentication(passwordAuthToken);
}
}
Solution
As @dur mentioned in comments, problem was that I miss a chain.doFilter(request, response);
line at the end of doFilterInternal
function.
Now it should look like following:
var header = request.getHeader(HttpHeaders.AUTHORIZATION);
if (header == null || !header.startsWith(jwtUtils.Bearer)) {
chain.doFilter(request, response);
return;
}
var jwt = header.replace(jwtUtils.Bearer, "");
var username = jwtUtils.extractUsername(jwt);
if (username == null && SecurityContextHolder.getContext().getAuthentication() != null) {
chain.doFilter(request, response);
return;
}
var user = userService.loadUserByUsername(username);
if (!jwtUtils.validateToken(jwt, user) || !user.isEnabled()) {
chain.doFilter(request, response);
return;
}
var passwordAuthToken = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
passwordAuthToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); // implies that request should contain user details?
SecurityContextHolder.getContext().setAuthentication(passwordAuthToken);
chain.doFilter(request, response);
Answered By - sirkostya009
Answer Checked By - Timothy Miller (JavaFixing Admin)