I have a Spring Boot app which uses spring security as a dependency. I am migrating Spring boot version from 2.7.16 to 3.2.1. Everything works fine in version 2.7.16. But in 3.2.1, the rest APIs give 403 after a while. Sometimes 5 mins later, sometimes 1 hour later. So, it gives 200 successful responses in the beginning, but gives 403 after some time. I couldn’t fix the issue after many attempts. I am sharing security configs. Any help is appreciated
2.7.16 security config;
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;
}
}
And here is 3.2.1 security config;
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;
}
}
Logs:
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
Show your Spring Security
DEBUG
logs.logs are added @dur
These are Jenkins logs, not your application log. I don’t understand the role of Jenkins in you question.
I shared app logs as well. Jenkins log is just a bonus. But above the Jenkins log, there is already application logs.
why are you posting app logs when we asked for
DEBUG
logs, please look up how to enable debug logsShow 2 more comments