java.lang.IllegalArgumentException:在未注册的Filter类之后无法注册

时间:2020-04-07 07:54:19

标签: java spring-boot spring-security

我正在使用spring boo开发登录服务。开发它时,我遇到了错误和类

org.springframework.beans.factory.BeanCreationException:在类路径资源[org / springframework / security / config / annotation / web / configuration / WebSecurityConfiguration.class]中创建名称为“ springSecurityFilterChain”的bean时出错:通过工厂实例化Bean方法失败;嵌套的异常是org.springframework.beans.BeanInstantiationException:无法实例化[javax.servlet.Filter]:工厂方法'springSecurityFilterChain'抛出了异常;嵌套异常为java.lang.IllegalArgumentException:在未注册的Filter类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类

@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 个答案:

答案 0 :(得分:2)

您正在尝试在jwtRequestFilter之前添加JwtFilter.class,这是在告诉Spring Security将自身置于自身之前。

您可以尝试将此行更改为:

http.addFilterBefore(jwtRequestFilter,UsernamePasswordAuthenticationFilter.class).authorizeRequests();

此外,Spring Boot中的每个Filter bean也会自动添加到您的默认servlet过滤器链中,因此在初始化之后,它将出现两次:

  1. 作为链中的Servlet过滤器
  2. 作为springSecurityFilterChain中的过滤器

如果您只想将其用作spring安全过滤器,请先删除@Component批注并自己实例化,然后再将其添加到springSecurityFilterChain中:

http.addFilterBefore(new JwtFilter(),UsernamePasswordAuthenticationFilter.class).authorizeRequests();

答案 1 :(得分:0)

如果使用Java config进行bean配置,则必须在WebInitializer类中注册过滤bean。

public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    //your configs

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