I am trying to perform JWT auth in spring boot and the request are getting stuck in redirect loop.
JWTAuthenticationProvider
@Component
public class JwtAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
@Autowired
private JwtUtil jwtUtil;
@Override
public boolean supports(Class<?> authentication) {
return (JwtAuthenticationToken.class.isAssignableFrom(authentication));
}
@Override
protected void additionalAuthenticationChecks(UserDetails userDetails,
UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
}
@Override
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException {
JwtAuthenticationToken jwtAuthenticationToken = (JwtAuthenticationToken) authentication;
String token = jwtAuthenticationToken.getToken();
JwtParsedUser parsedUser = jwtUtil.parseToken(token);
if (parsedUser == null) {
throw new JwtException("JWT token is not valid");
}
UserDetails user = User.withUsername(parsedUser.getUserName()).password("temp_password").authorities(parsedUser.getRole()).build();
return user;
}
JwtAuthenticationFilter
public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
super("/**");
this.setAuthenticationManager(authenticationManager);
}
@Override
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
return true;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
String header = request.getHeader("Authorization");
if (header == null || !header.startsWith("Bearer ")) {
throw new JwtException("No JWT token found in request headers");
}
String authToken = header.substring(7);
JwtAuthenticationToken authRequest = new JwtAuthenticationToken(authToken);
return getAuthenticationManager().authenticate(authRequest);
}
@Override
protected void successfulAuthentication(HttpServletRequest request,
HttpServletResponse response, FilterChain chain, Authentication authResult)
throws IOException, ServletException {
super.successfulAuthentication(request, response, chain, authResult);
chain.doFilter(request, response);
}
}
SecurityConfiguration
@Configuration
@EnableWebSecurity(debug = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationProvider jwtAuthenticationProvider;
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(jwtAuthenticationProvider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().antMatchers("/secured-resource-1/**", "/secured-resource-2/**")
.hasRole("ADMIN").antMatchers("/secured-resource-2/**").hasRole("ADMIN").and().formLogin()
.successHandler(new AuthenticationSuccessHandler()).and().httpBasic().and().exceptionHandling()
.accessDeniedHandler(new CustomAccessDeniedHandler()).authenticationEntryPoint(getBasicAuthEntryPoint())
.and()
.addFilterBefore(new JwtAuthenticationFilter(authenticationManager()),
FilterSecurityInterceptor.class)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Bean
public CustomBasicAuthenticationEntryPoint getBasicAuthEntryPoint() {
return new CustomBasicAuthenticationEntryPoint();
}
}
MainController
@RestController
public class MainController {
@Autowired
private JwtUtil jwtUtil;
@GetMapping("/secured-resource-1")
public String securedResource1() {
return "Secured resource1";
}
}
When I hit the endpoint with the valid JWT token, the code goes in a loop from Filter to provider class and ends in Error:
Exceeded maxRedirects. Probably stuck in a redirect loop http://localhost:8000/ error.
Debug logs shows the following error:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: Cannot call sendError() after the response has been committed] with root cause
java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
Any suggestions what am I missing here. Thanks in advance.