Spring Security 6未调用自定义CustomAuthenticationProvider问题求助
问题分析与解决:Spring Security自定义AuthenticationProvider未被调用
问题背景
我的Spring Security配置定义如下:
@Configuration @EnableWebSecurity public class SecurityConfiguration { private final CustomAuthenticationProvider customAuthenticationProvider; @Autowired public SecurityConfiguration(CustomAuthenticationProvider customAuthenticationProvider) { this.customAuthenticationProvider = customAuthenticationProvider; } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .cors(CorsConfigurer::disable) // Disable CORS .csrf().disable() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authenticationProvider(customAuthenticationProvider) .authorizeHttpRequests(authorizeRequests -> authorizeRequests .requestMatchers(HttpMethod.GET, "/health", "/public/**").permitAll() .requestMatchers("/api/**", "/events/**", "/competition/**").authenticated() ) .httpBasic(); return http.build(); } }
/static和/public路径的请求能正常被允许访问,但/events、/api、/competition下的请求都会触发AnonymousAuthenticationFilter。请求/events/1时的日志如下:
20:05:06.483 [http-nio-8080-exec-8] DEBUG o.s.security.web.FilterChainProxy - Securing GET /events/1 20:05:06.483 [http-nio-8080-exec-8] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext 20:05:06.484 [http-nio-8080-exec-8] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped to com.pr.golf.golfapp.controller.EventsController#getEvent(Long) 20:05:06.486 [http-nio-8080-exec-8] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped to com.pr.golf.golfapp.controller.EventsController#getEvent(Long) 20:05:06.487 [http-nio-8080-exec-8] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped to com.pr.golf.golfapp.controller.EventsController#getEvent(Long) 20:05:06.488 [http-nio-8080-exec-8] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped to com.pr.golf.golfapp.controller.EventsController#getEvent(Long) 20:05:06.490 [http-nio-8080-exec-8] DEBUG o.s.security.web.FilterChainProxy - Securing GET /error 20:05:06.491 [http-nio-8080-exec-8] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse) 20:05:06.492 [http-nio-8080-exec-8] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse) 20:05:06.493 [http-nio-8080-exec-8] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse) 20:05:06.495 [http-nio-8080-exec-8] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse) 20:05:06.498 [http-nio-8080-exec-8] DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse) 20:05:06.498 [http-nio-8080-exec-8] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
原因分析
你的CustomAuthenticationProvider未被调用,核心原因是认证流程没有被触发:
- 你配置了
.httpBasic(),意味着Spring Security会通过HttpBasicAuthenticationFilter处理认证,但这个过滤器只会在请求携带Authorization: Basic <Base64编码的用户名:密码>头时才会启动认证流程,调用配置的AuthenticationProvider。 - 如果请求没有携带这个认证头,Spring Security会认为当前是匿名请求,直接触发
AnonymousAuthenticationFilter,不会调用自定义的AuthenticationProvider,最终因为请求需要认证但没有有效身份,跳转到错误页面。
解决方案
根据你的认证需求,有两种处理方式:
方式一:使用Http Basic认证(符合当前配置)
确保请求携带正确的Http Basic认证头:
- 将用户名和密码用冒号拼接(比如
user:password) - 对拼接后的字符串进行Base64编码
- 在请求头中添加
Authorization: Basic <编码后的字符串>
例如,用curl发送请求:
curl -H "Authorization: Basic dXNlcjpwYXNzd29yZA==" http://localhost:8080/events/1
(其中dXNlcjpwYXNzd29yZA==是user:password的Base64编码)
方式二:自定义认证过滤器(如果不用Http Basic)
如果你的认证方式不是Http Basic(比如Token认证),需要添加自定义过滤器来触发认证流程:
- 编写一个自定义过滤器,从请求中提取认证凭证(比如Token)
- 创建
Authentication对象(比如UsernamePasswordAuthenticationToken或自定义实现) - 调用
AuthenticationManager.authenticate(authentication)方法,这会自动触发你的CustomAuthenticationProvider - 将认证成功后的
Authentication对象存入SecurityContextHolder
示例代码:
public class CustomAuthFilter extends OncePerRequestFilter { private final AuthenticationManager authenticationManager; public CustomAuthFilter(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 从请求头提取Token String token = request.getHeader("X-Auth-Token"); if (token != null) { // 创建Authentication对象 Authentication authRequest = new UsernamePasswordAuthenticationToken(null, token); // 触发认证,会调用CustomAuthenticationProvider Authentication authResult = authenticationManager.authenticate(authRequest); // 存入SecurityContext SecurityContextHolder.getContext().setAuthentication(authResult); } filterChain.doFilter(request, response); } }
然后在Security配置中添加这个过滤器:
@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .cors(CorsConfigurer::disable) .csrf().disable() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authenticationProvider(customAuthenticationProvider) .addFilterBefore(new CustomAuthFilter(authenticationManager(http)), UsernamePasswordAuthenticationFilter.class) .authorizeHttpRequests(authorizeRequests -> authorizeRequests .requestMatchers(HttpMethod.GET, "/health", "/public/**").permitAll() .requestMatchers("/api/**", "/events/**", "/competition/**").authenticated() ); return http.build(); } // 暴露AuthenticationManager @Bean public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception { return http.getSharedObject(AuthenticationManagerBuilder.class) .authenticationProvider(customAuthenticationProvider) .build(); }
内容的提问来源于stack exchange,提问作者mvarta
相关产品推荐
相关产品推荐

