Spring Security 6 + Spring Boot中permitAll()失效问题求助
在Spring Boot项目中基于Spring Security 6配置了自定义SecurityFilterChain,采用JWT认证。为测试将/home路由设置为permitAll(),但即使禁用了httpBasic和formLogin认证,访问该路由仍返回401未授权。之后从@SpringBootApplication中排除了SpringAutoConfiguration类,却出现了白标错误页面。作为Spring新手,尝试过多种HttpSecurity配置变体但未解决问题。
安全配置类代码
@Configuration @EnableWebSecurity public class AppConfig { public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { // simple httpSecurity just to check // return http.sessionManagement(s -> // s.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // .authorizeRequests(auth -> auth // .requestMatchers("/home").permitAll() // .anyRequest().authenticated()) //// .httpBasic(Customizer.withDefaults()) //// .formLogin(FormLoginConfigurer::disable) // .build(); // original code which I want to work with. return http .authorizeHttpRequests(auth -> auth // .requestMatchers(HttpMethod.GET, "/").permitAll() // .requestMatchers(HttpMethod.POST,"/api/auth/**").permitAll() .requestMatchers("/home").permitAll() .anyRequest().authenticated()) .addFilterBefore(new JwtTokenValidationFilter(), BasicAuthenticationFilter.class) .httpBasic(HttpBasicConfigurer::disable) //// .csrf(AbstractHttpConfigurer::disable) //// .cors(corsConfigurer -> corsConfigurer //// .configurationSource(request -> { //// CorsConfiguration cors = new CorsConfiguration(); //// cors.setAllowedOrigins(List.of("http://localhost:3000")); //// cors.setAllowedMethods(List.of("*")); //// cors.setAllowCredentials(true); //// cors.setAllowedHeaders(List.of("*")); //// cors.setExposedHeaders(List.of("Authorization")); //// cors.setMaxAge(3600L); //// return cors; //// })) .build(); // return http.build(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
控制器代码
@RestController public class HomeController { @GetMapping("/home") public String homeController() { return "Hello from Home"; } }
可提供JWTUtil和JWTValidation类的代码。尝试过构建自定义SecurityFilterChain并通过JWT实现认证,也查找过Stack Overflow上的解决方案但均为旧版本内容,仍未找到问题所在。
问题排查与解决方案
1. 401未授权的核心原因:JWT过滤器拦截了/home请求
你添加的JwtTokenValidationFilter会在BasicAuthenticationFilter之前执行,而这个过滤器可能没有对/home路由做放行处理,导致即使配置了permitAll(),过滤器依然会校验JWT令牌,没有令牌就返回401。
解决步骤:
修改JwtTokenValidationFilter的doFilterInternal方法,先判断请求路径是否是/home,如果是则直接放行:
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 放行/home路由 if (request.getRequestURI().equals("/home")) { filterChain.doFilter(request, response); return; } // 原有JWT校验逻辑 String token = extractTokenFromRequest(request); if (token != null && validateToken(token)) { // 设置认证信息到SecurityContext Authentication auth = getAuthentication(token); SecurityContextHolder.getContext().setAuthentication(auth); } else { // 无有效令牌时返回401 response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid or missing JWT token"); return; } filterChain.doFilter(request, response); }
2. 排除SpringAutoConfiguration导致白标错误的原因
SpringAutoConfiguration包含了Spring Boot的核心自动配置,排除它会导致大量必要的配置(比如DispatcherServlet、视图解析器等)无法生效,从而出现白标错误页面。绝对不要排除这个类,直接恢复@SpringBootApplication的原始写法即可:
@SpringBootApplication public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } }
3. 优化SecurityFilterChain配置(核心修正)
你的securityFilterChain方法没有添加@Bean注解!这会导致Spring无法识别并使用这个自定义的过滤器链,而是使用默认的Security配置,这很可能是配置不生效的根本原因。修正后的配置:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { return http .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests(auth -> auth .requestMatchers("/home").permitAll() .anyRequest().authenticated()) .addFilterBefore(new JwtTokenValidationFilter(), BasicAuthenticationFilter.class) .httpBasic(HttpBasicConfigurer::disable) .formLogin(FormLoginConfigurer::disable) // 显式禁用表单登录 .csrf(AbstractHttpConfigurer::disable) // JWT场景下建议禁用CSRF .build(); }
4. 验证步骤
- 给
securityFilterChain方法添加@Bean注解 - 修改JWT过滤器放行
/home路由 - 恢复
@SpringBootApplication的原始配置 - 重启项目,访问
/home应该能正常返回"Hello from Home"
内容的提问来源于stack exchange,提问作者Sidhart Singh

