2

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();
    }
}
2
  • if you have an implementation of WebSecurityConfigurerAdapter, could you add it? Commented Apr 7, 2020 at 8:47
  • @pero_hero i add the class Commented Apr 7, 2020 at 10:14

3 Answers 3

10

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:

  1. as a Servlet Filter in your chain
  2. 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();
Sign up to request clarification or add additional context in comments.

1 Comment

@Component annotation is what go me. Thanks. #dontDoubleUp
0

If you are using java config for bean configuration you have to register your filter bean in WebInitializer class.

public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    //your configs

    @Override
    protected Filter[] getServletFilters() {
        DelegatingFilterProxy filterProxy = new DelegatingFilterProxy();
        filterProxy.setTargetBeanName("jwtFilter");
        return new Filter[]{filterProxy};
    }
}

Comments

0

The list of filters to put in the *class part can be retrieved by increasing the debug level on spring security. Any filters there will work.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.