Describe the bug
After updating to Spring Security 6.1.4 (as part of Spring Boot 3.1.4), the authentication context is not being populated and SecurityContextHolder.getContext().getAuthentication() returns null.
The issue seems to come from updating this concrete dependency:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>6.1.4</version>
</dependency>
Version 6.1.3 works fine.
After further investigation, it turns out this particular code in our application causes the authentication object to be null, but not sure why:
@Configuration
@EnableMethodSecurity
public class MethodSecurityConfig {
@Bean
static MethodSecurityExpressionHandler methodSecurityExpressionHandler() {
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
return new DefaultMethodSecurityExpressionHandler();
}
}
Expected behavior Authentication context should be populated from the HTTP request Authentication header (JWT Bearer token). The setup is a standard Spring Boot application with Spring MVC and Spring Security (Web Security Config).
Let me know if you need more information.
Regards, Momchil
Comment From: marcusdacoregio
Hi, @m-ignatov. Thanks for the report.
Can you put together a minimal sample that reproduces the problem?
Comment From: m-ignatov
Hi, @marcusdacoregio
You can find a minimal sample here: https://github.com/m-ignatov/spring-security-xsuaa-usage
Running the included Spring Boot tests can reproduce the issue.
Regards, Momchil
Comment From: marcusdacoregio
Hello, @m-ignatov. Thank you for the sample, it was really useful.
I think that the problem is only happening in 6.1.4 because of this fix https://github.com/spring-projects/spring-security/issues/13814. In summary, we delay the initialization of the MethodSecurityExpressionHandler until it is needed, therefore the line SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL); inside your bean won't be evaluated at startup time and the Spring Security components will be using another strategy.
But the problem is how and where you configured the SecurityContextHolderStrategy. The Spring Security components, since 6.0, look for a @Bean of SecurityContextHolderStrategy to use, or, if the bean is not present, it will use what is in SecurityContextHolder.getContextHolderStrategy().
With that said, we need to make sure that we expose a SecurityContextHolderStrategy bean and do not try to configure it inside other bean declaration. Your configuration will look like this:
@Bean
static SecurityContextHolderStrategy securityContextHolderStrategy() {
SecurityContextHolder.setStrategyName(MODE_INHERITABLETHREADLOCAL);
return SecurityContextHolder.getContextHolderStrategy();
}
@Bean
static MethodSecurityExpressionHandler methodSecurityExpressionHandler() {
return new DefaultMethodSecurityExpressionHandler();
}
I'll close this as solved since the problem is in the configuration and not a bug.