簡體   English   中英

java.lang.IllegalArgumentException:在未注冊的過濾器 class 后無法注冊

[英]java.lang.IllegalArgumentException: Cannot register after unregistered Filter class

我正在使用 spring boo 開發登錄服務。 在開發它時我得到了以下錯誤和 class

org.springframework.beans.factory.BeanCreationException:在 class 路徑資源 [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class] 中創建名稱為“springSecurityFilterChain”的 bean 時出錯:通過工廠方法實例化 bean 失敗; 嵌套異常是 org.springframework.beans.BeanInstantiationException:無法實例化 [javax.servlet.Filter]:工廠方法“springSecurityFilterChain”拋出異常; 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();
    }
}

您正在嘗試在jwtRequestFilter之前添加JwtFilter.class ,這有點告訴 spring 安全性將自身置於自身之上。

您可以嘗試將此行更改為:

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

此外,spring 引導中的每個Filter bean 也會自動添加到您的默認 servlet 過濾器鏈中,因此在初始化后,它將出現兩次:

  1. 作為鏈中的 Servlet 過濾器
  2. 作為 springSecurityFilterChain 中的過濾器

如果您只想將其用作 spring 安全過濾器,請刪除@Component注釋並在將其添加到 springSecurityFilterChain 之前自行實例化它:

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

如果您使用 java 配置進行 bean 配置,則必須在 WebInitializer class 中注冊您的過濾器 bean。

public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    //your configs

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

可以通過提高 spring 安全性的調試級別來檢索要放入 *class 部分的過濾器列表,那里的任何過濾器都可以工作

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM