Spring Boot 2.7.16迁移至3.2.1后API间歇性返回403求助
Spring Boot 2.7.16 迁移至3.2.1后REST API间歇性返回403问题求助
我有一个依赖Spring Security的Spring Boot应用,正从2.7.16版本迁移至3.2.1版本。在2.7.16版本中一切正常,但升级到3.2.1后,REST API会在运行一段时间后(时长不定,有时5分钟,有时1小时)返回403状态码。初始阶段API能正常返回200,但一段时间后就会出现403。多次尝试仍未解决问题,现将新旧版本的安全配置及相关日志分享出来,恳请各位提供帮助。
2.7.16版本安全配置
import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider; import org.springframework.security.web.authentication.preauth.PreAuthenticatedGrantedAuthoritiesUserDetailsService; import org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter; @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) @RequiredArgsConstructor public class SecurityConfiguration { private final AuthenticationConfiguration configuration; @Bean protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() .antMatchers("/h2-console/**").permitAll() .antMatchers("/manage/info").permitAll() .antMatchers("/manage/health").permitAll() .anyRequest().authenticated() .and() .addFilter(authenticationFilter()) .csrf().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .httpBasic() .and() .headers().frameOptions().disable(); return http.build(); } @Bean public AuthenticationManager authenticationManager() throws Exception { return configuration.getAuthenticationManager(); } @Bean public RequestHeaderAuthenticationFilter authenticationFilter() throws Exception { RequestHeaderAuthenticationFilter filter = new RequestHeaderAuthenticationFilter(); filter.setPrincipalRequestHeader(HeaderConstants.PRINCIPAL_HEADER); filter.setExceptionIfHeaderMissing(false); filter.setAuthenticationManager(authenticationManager()); filter.setAuthenticationDetailsSource(new HeaderAuthenticationDetailsSource()); return filter; } @Bean public PreAuthenticatedAuthenticationProvider authenticationProvider() { PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider(); provider.setPreAuthenticatedUserDetailsService(new PreAuthenticatedGrantedAuthoritiesUserDetailsService()); return provider; } }
3.2.1版本安全配置
import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider; import org.springframework.security.web.authentication.preauth.PreAuthenticatedGrantedAuthoritiesUserDetailsService; import org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter; import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher; @Configuration @EnableWebSecurity @EnableMethodSecurity @RequiredArgsConstructor public class SecurityConfiguration { private final AuthenticationConfiguration configuration; @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(auth -> auth .requestMatchers(antMatcher("/h2-console/**")).permitAll() .requestMatchers(antMatcher("/manage/info")).permitAll() .requestMatchers(antMatcher("/manage/health")).permitAll() .anyRequest().authenticated() ) .addFilter(authenticationFilter()) .headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable)) ; return http.build(); } @Bean public AuthenticationManager authenticationManager() throws Exception { return configuration.getAuthenticationManager(); } @Bean public RequestHeaderAuthenticationFilter authenticationFilter() throws Exception { RequestHeaderAuthenticationFilter filter = new RequestHeaderAuthenticationFilter(); filter.setPrincipalRequestHeader(HeaderConstants.PRINCIPAL_HEADER); filter.setExceptionIfHeaderMissing(false); filter.setAuthenticationManager(authenticationManager()); filter.setAuthenticationDetailsSource(new HeaderAuthenticationDetailsSource()); return filter; } @Bean public PreAuthenticatedAuthenticationProvider authenticationProvider() { PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider(); provider.setPreAuthenticatedUserDetailsService(new PreAuthenticatedGrantedAuthoritiesUserDetailsService()); return provider; } }
相关日志
2024-01-05T18:59:40.276Z DEBUG 1 --- [xxxx-time] [nio-8061-exec-2] o.s.s.w.a.Http403ForbiddenEntryPoint : Pre-authenticated entry point called. Rejecting access 2024-01-05T18:59:40.279Z DEBUG 1 --- [xxxx-time] [nio-8061-exec-2] o.s.security.web.FilterChainProxy : Securing GET /error 2024-01-05T18:59:40.281Z DEBUG 1 --- [xxxx-time] [nio-8061-exec-2] o.s.security.web.FilterChainProxy : Secured GET /error 2024-01-05T18:59:40.282Z DEBUG 1 --- [xxxx-time] [nio-8061-exec-2] o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for GET "/error", parameters={} 2024-01-05T18:59:40.282Z DEBUG 1 --- [xxxx-time] [nio-8061-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest) 2024-01-05T18:59:40.283Z DEBUG 1 --- [xxxx-time] [nio-8061-exec-2] o.j.s.OpenEntityManagerInViewInterceptor : Opening JPA EntityManager in OpenEntityManagerInViewInterceptor 2024-01-05T18:59:40.284Z DEBUG 1 --- [xxxx-time] [nio-8061-exec-2] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/json', given [*/*] and supported [application/json, application/*+json, application/cbor] 2024-01-05T18:59:40.285Z DEBUG 1 --- [xxxx-time] [nio-8061-exec-2] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [{timestamp=Fri Jan 05 18:59:40 GMT 2024, status=403, error=Forbidden, path=/worklogEntries/health}] 2024-01-05T18:59:40.288Z DEBUG 1 --- [xxxx-time] [nio-8061-exec-2] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor 2024-01-05T18:59:40.288Z DEBUG 1 --- [xxxx-time] [nio-8061-exec-2] o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 403
内容的提问来源于stack exchange,提问作者Gökhan Polat
相关产品推荐
相关产品推荐

