I am developing login service using spring boo. when developing it I got below error and the class
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.IllegalArgumentException: Cannot register after unregistered Filter class com.jwt.logincservice.filter.JwtFilter
@Component
public class JwtFilter extends OncePerRequestFilter {
@Autowired
private MyUserDetailsService userDetailsService;
@Autowired
private Jwtutil jwtUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
final String authorizationHeader = request.getHeader("Authorization");
String username = null;
String jwt = null;
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
jwt = authorizationHeader.substring(7);
username = jwtUtil.extractUsername(jwt);
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (jwtUtil.validateToken(jwt, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
chain.doFilter(request, response);
}
}
WebSecurityConfigurerAdapter class
@EnableWebSecurity
public class SecurityConfigureAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private MyUserDetailsService myUseserDeatailService;
@Autowired
private JwtFilter jwtRequestFilter;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUseserDeatailService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests().antMatchers("/authentication").permitAll()
.anyRequest().authenticated()
.and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(jwtRequestFilter, JwtFilter.class).authorizeRequests();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
you are trying to add the jwtRequestFilter
before the JwtFilter.class
which is kind of telling spring security to put itself before itself.
can you try changing this line to:
http.addFilterBefore(jwtRequestFilter,UsernamePasswordAuthenticationFilter.class).authorizeRequests();
additionally, every Filter
bean in spring boot is automatically added also to your default servlet filter chain, so after initialization, it will be present twice:
- as a Servlet Filter in your chain
- as a Filter in your springSecurityFilterChain
if you just want to use it as a spring security filter remove the @Component
annotation and instantiate it by yourself before adding it to the springSecurityFilterChain:
http.addFilterBefore(new JwtFilter(),UsernamePasswordAuthenticationFilter.class).authorizeRequests();