我正在尝试获取两个过滤器,一个用于捕获 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/ .
这与
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)