Spring Security 6使用authorizeHttpRequests时403:AuthenticationProvider未调用
问题根源
替换authorizeRequests为authorizeHttpRequests后,Spring Security的过滤器链执行逻辑和授权流程发生了变更。如果认证过滤器未被正确加入链中或顺序不对,会导致ProviderManager无法触发,预认证Token得不到处理,最终授权判断时isAuthenticated()返回false,触发403错误。
修复步骤
1. 显式添加认证过滤器到SecurityFilterChain
构建SecurityFilterChain时,必须把认证相关过滤器(自定义认证过滤器、UsernamePasswordAuthenticationFilter等)明确加入链中,且要放在authorizeHttpRequests配置之前。示例代码:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 先加认证过滤器,保证ProviderManager能被触发 .addFilterBefore(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) // 配置授权规则 .authorizeHttpRequests(auth -> auth .requestMatchers("/public/**").permitAll() .anyRequest().authenticated() ) // 根据实际需求禁用不必要的配置 .csrf(csrf -> csrf.disable()); return http.build(); }
2. 正确注册AuthenticationProvider
确保自定义的AuthenticationProvider实例被正确注册到AuthenticationManager中,示例:
@Bean public AuthenticationManager authenticationManager(List<AuthenticationProvider> providers) { return new ProviderManager(providers); } // 自定义AuthenticationProvider示例 @Bean public AuthenticationProvider customAuthenticationProvider() { return new CustomAuthenticationProvider(); }
3. 配置预认证Token处理逻辑
如果用了预认证机制(比如PreAuthenticatedAuthenticationToken),要确保对应的过滤器(如RequestHeaderAuthenticationFilter)配置正确,且会把Token提交给AuthenticationManager处理:
@Bean public RequestHeaderAuthenticationFilter preAuthFilter(AuthenticationManager authManager) { RequestHeaderAuthenticationFilter filter = new RequestHeaderAuthenticationFilter(); filter.setAuthenticationManager(authManager); // 设置预认证Token对应的请求头 filter.setPrincipalRequestHeader("X-Auth-User"); filter.setCredentialsRequestHeader("X-Auth-Token"); // 认证失败时终止过滤器链,避免后续授权逻辑出错 filter.setContinueFilterChainOnUnsuccessfulAuthentication(false); return filter; }
4. 检查授权规则顺序
使用authorizeHttpRequests时,请求匹配器的优先级由配置顺序决定,先配置公共资源的permitAll,再配置其他请求的authenticated,避免规则被覆盖。
重要提示
- Spring Security 6.0中
authorizeHttpRequests是authorizeRequests的替代方案,采用了新的授权决策机制,必须保证认证流程在授权流程之前执行。 - 自定义过滤器一定要通过
addFilterBefore/addFilterAfter指定在链中的位置,避免自动排序导致顺序错误。
内容的提问来源于stack exchange,提问作者Shorn
相关产品推荐
相关产品推荐

