Bean Order 值神秘地为空

问题描述 投票:0回答:1

我正在尝试获取两个过滤器,一个用于捕获 jwt,另一个用于捕获 API 密钥。这是我的代码:

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    
    @Autowired
    private JwtRequestFilter jwtRequestFilter;
    
    @Autowired
    private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
    
    @Autowired
    private ApiKeyRequestFilter apiKeyRequestFilter;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth, UserDetailsService userDetailsService) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }


    @Bean
    @Order(1)
    SecurityFilterChain jwtFilterChain(HttpSecurity http) throws Exception {
            return http
                .cors().and().csrf().disable()
                .authorizeRequests()
                    .antMatchers(
                            "/authenticate",
                            "/register",
                            "/refresh",
                            "/post_appointment",
                            "/delete_appointment",
                            "/get_times",
                            "/get_services",
                            "/sendResetPassword",
                            "/sendSupport",
                            "/paymentWebhook",
                            "/api**")
                        .permitAll()
                    .anyRequest().authenticated()
                .and()
                .exceptionHandling()
                    .authenticationEntryPoint(jwtAuthenticationEntryPoint)
                .and()
                .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class).build();
       }

    @Bean
    @Order(2)
    SecurityFilterChain APIFilterChainConfig(HttpSecurity http) throws Exception {
            return http
                .cors().and().csrf().disable()
                .authorizeRequests()
                    .antMatchers("/api/**")
                        .permitAll()
                    .anyRequest().authenticated()
                .and()
                .addFilterBefore(apiKeyRequestFilter, JwtRequestFilter.class).build();
    }
}

运行此命令会出现此错误:

Error creating bean with name 'APIFilterChainConfig' defined in class path resource [com/reporter/config/SecurityConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.web.SecurityFilterChain]: Factory method 'APIFilterChainConfig' threw exception; nested exception is java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "org.springframework.security.config.annotation.web.builders.FilterOrderRegistration.getOrder(java.lang.Class)" is null

这很令人困惑,因为我清楚地设置了顺序。是不是过滤器本身的问题?这不是很清楚,所以任何帮助将不胜感激。我还将添加这是根据此页面实现安全配置现代化的更大努力的一部分:https://www.danvega.dev/blog/2023/04/20/multiple-spring-security-configs/ .

java spring security
1个回答
0
投票

这与

SecurityFilterChain
的顺序无关,而是关于特定
SecurityFilterChain
内过滤器的顺序。问题来自
APIFilterChainConfig

中的以下行
.addFilterBefore(apiKeyRequestFilter, JwtRequestFilter.class)

addFilterBefore()

中指定的过滤器类应该是 spring security 内置过滤器,其顺序在 
this 中显式定义,或者是在 spring 之前成功定义为添加到相同 SecurityFilterChain
 的过滤器安全性有足够的信息来知道应该将 
apiKeyRequestFilter
 添加到哪个过滤器链位置。

JwtRequestFilter

显然不是Spring Security内置过滤器,因此Spring Security不知道其顺序值来做出这样的决定,因此抛出此异常。

要解决此问题,您必须根据知道其顺序值的内置过滤器之一将

apiKeyRequestFilter

 添加到 
SecurityFilterChain
,如果有意义的话,可能就在 
UsernamePasswordAuthenticationFilter
 之前:

.addFilterBefore(apiKeyRequestFilter,UsernamePasswordAuthenticationFilter.class)
    
© www.soinside.com 2019 - 2024. All rights reserved.