Spring Security过滤器未触发:原因排查与解决方法咨询
以下是针对你遇到的过滤器未触发、未授权请求可访问受保护资源问题的具体原因分析和修复方案:
1. JWT授权过滤器逻辑错误,导致未校验请求直接通过
你的JwtAuthorizationFilter中,当Token不存在或格式不符合要求时,先调用了filterChain.doFilter(request, response)再设置401状态码,这会让请求直接进入后续处理链,绕过认证校验,导致无需Token即可访问资源。
修复代码:
调整doFilterInternal中的逻辑,先设置响应状态,再终止请求链,不执行后续过滤:
if (jwtToken == null || !jwtToken.startsWith(SecParams.HEADER_PREFIX)) { System.out.println("null or doesn't start with Bearer"); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return; // 终止请求,不继续执行后续过滤器 }
2. 自定义认证过滤器未指定拦截路径
你继承的UsernamePasswordAuthenticationFilter默认拦截/login路径,但自定义的JwtAuthenticationFilter没有显式设置拦截规则,可能导致登录请求不会触发该过滤器,进而无法生成Token。
修复代码:
在JwtAuthenticationFilter的构造方法中添加拦截路径配置:
public JwtAuthenticationFilter(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; // 指定拦截/login路径的POST请求 setFilterProcessesUrl("/login"); setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login", "POST")); }
3. OPTIONS请求处理中断过滤器链
JwtAuthorizationFilter中处理OPTIONS预检请求时,仅设置了200状态码但未调用filterChain.doFilter,会导致请求链中断,影响后续过滤器执行,同时可能引发跨域问题。
修复代码:
处理OPTIONS请求时,设置状态后继续执行过滤器链:
if (request.getMethod().equals("OPTIONS")) { response.setStatus(HttpServletResponse.SC_OK); filterChain.doFilter(request, response); // 继续执行后续过滤 return; }
4. 过滤器添加顺序不合理
你先添加了JwtAuthenticationFilter,再添加JwtAuthorizationFilter,可能导致授权校验在认证之后执行,不符合逻辑(授权校验应该对所有非/login请求生效)。
修复代码:
调整过滤器添加顺序,先添加授权过滤器:
@Override public void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/login").permitAll() .anyRequest().authenticated() .and() .addFilterBefore(new JwtAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class) .addFilter(new JwtAuthenticationFilter(authenticationManager())) .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); }
5. Security配置类未被Spring扫描
如果SecurityConfig所在的包不在Spring Boot的组件扫描范围内,整个安全配置不会生效,过滤器也不会被加载。
修复方案:
- 确保
SecurityConfig类上的@Configuration和@EnableWebSecurity注解生效 - 确认该类所在包被
@SpringBootApplication的默认扫描范围覆盖,或手动添加@ComponentScan指定包路径
可选:添加CORS配置(解决跨域导致的请求异常)
若前端存在跨域请求,未正确配置CORS会导致预检请求失败,进而影响过滤器触发。可以在SecurityConfig中添加CORS配置:
代码示例:
@Override public void configure(HttpSecurity http) throws Exception { http.cors().and() // 启用CORS配置 .csrf().disable() .authorizeRequests() .antMatchers("/login").permitAll() .anyRequest().authenticated() .and() .addFilterBefore(new JwtAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class) .addFilter(new JwtAuthenticationFilter(authenticationManager())) .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); } @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000")); // 替换为你的前端地址 configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); configuration.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type")); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; }
内容的提问来源于stack exchange,提问作者Hajji Achref

