1
0
mirror of synced 2026-08-04 09:17:02 +00:00

Move Authority Propagation Into Filters

Given that the filters are the level at which the
SecurityContextHolder is consulted, this commit moves
the operation that ProviderManager was doing into each
authentication filter.

Issue gh-17862
This commit is contained in:
Josh Cummings
2025-08-29 13:14:21 -06:00
parent a0fe6a5fee
commit 3f774548d2
17 changed files with 60 additions and 138 deletions
@@ -18,14 +18,10 @@ package org.springframework.security.config.annotation.authentication.builders;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.security.authentication.AuthenticationEventPublisher;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
@@ -41,8 +37,6 @@ import org.springframework.security.config.annotation.authentication.configurers
import org.springframework.security.config.annotation.authentication.configurers.userdetails.DaoAuthenticationConfigurer;
import org.springframework.security.config.annotation.authentication.configurers.userdetails.UserDetailsAwareConfigurer;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.util.Assert;
@@ -241,10 +235,6 @@ public class AuthenticationManagerBuilder
if (this.eventPublisher != null) {
providerManager.setAuthenticationEventPublisher(this.eventPublisher);
}
SecurityContextHolderStrategy securityContextHolderStrategy = getBeanProvider(
SecurityContextHolderStrategy.class)
.getIfUnique(SecurityContextHolder::getContextHolderStrategy);
providerManager.setSecurityContextHolderStrategy(securityContextHolderStrategy);
providerManager = postProcess(providerManager);
return providerManager;
}
@@ -293,24 +283,4 @@ public class AuthenticationManagerBuilder
return configurer;
}
private <C> ObjectProvider<C> getBeanProvider(Class<C> clazz) {
BeanFactory beanFactory = getSharedObject(BeanFactory.class);
return (beanFactory != null) ? beanFactory.getBeanProvider(clazz) : new SingleObjectProvider<>(null);
}
private static final class SingleObjectProvider<O> implements ObjectProvider<O> {
private final @Nullable O object;
private SingleObjectProvider(@Nullable O object) {
this.object = object;
}
@Override
public Stream<O> stream() {
return Stream.ofNullable(this.object);
}
}
}
@@ -27,7 +27,6 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.aop.target.LazyInitTargetSource;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
@@ -84,7 +83,6 @@ public class AuthenticationConfiguration {
AuthenticationEventPublisher authenticationEventPublisher = getAuthenticationEventPublisher(context);
DefaultPasswordEncoderAuthenticationManagerBuilder result = new DefaultPasswordEncoderAuthenticationManagerBuilder(
objectPostProcessor, defaultPasswordEncoder);
result.setSharedObject(BeanFactory.class, this.applicationContext);
if (authenticationEventPublisher != null) {
result.authenticationEventPublisher(authenticationEventPublisher);
}
@@ -318,7 +318,6 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
.postProcess(new DefaultAuthenticationEventPublisher());
this.auth = new AuthenticationManagerBuilder(this.objectPostProcessor);
this.auth.authenticationEventPublisher(eventPublisher);
this.auth.setSharedObject(BeanFactory.class, this.context);
configure(this.auth);
this.authenticationManager = (this.disableAuthenticationRegistry)
? getAuthenticationConfiguration().getAuthenticationManager() : this.auth.build();
@@ -21,7 +21,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
@@ -117,7 +116,6 @@ class HttpSecurityConfiguration {
LazyPasswordEncoder passwordEncoder = new LazyPasswordEncoder(this.context);
AuthenticationManagerBuilder authenticationBuilder = new DefaultPasswordEncoderAuthenticationManagerBuilder(
this.objectPostProcessor, passwordEncoder);
authenticationBuilder.setSharedObject(BeanFactory.class, this.context);
authenticationBuilder.parentAuthenticationManager(authenticationManager());
authenticationBuilder.authenticationEventPublisher(getAuthenticationEventPublisher());
HttpSecurity http = new HttpSecurity(this.objectPostProcessor, authenticationBuilder, createSharedObjects());
@@ -162,10 +162,8 @@ public class WebAuthnConfigurer<H extends HttpSecurityBuilder<H>>
WebAuthnRelyingPartyOperations rpOperations = webAuthnRelyingPartyOperations(userEntities, userCredentials);
PublicKeyCredentialCreationOptionsRepository creationOptionsRepository = creationOptionsRepository();
WebAuthnAuthenticationFilter webAuthnAuthnFilter = new WebAuthnAuthenticationFilter();
ProviderManager manager = new ProviderManager(
new WebAuthnAuthenticationProvider(rpOperations, userDetailsService));
manager.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
webAuthnAuthnFilter.setAuthenticationManager(manager);
webAuthnAuthnFilter.setAuthenticationManager(
new ProviderManager(new WebAuthnAuthenticationProvider(rpOperations, userDetailsService)));
WebAuthnRegistrationFilter webAuthnRegistrationFilter = new WebAuthnRegistrationFilter(userCredentials,
rpOperations);
PublicKeyCredentialCreationOptionsFilter creationOptionsFilter = new PublicKeyCredentialCreationOptionsFilter(
@@ -30,8 +30,6 @@ import org.springframework.security.authentication.ObservationAuthenticationMana
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.BeanIds;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
@@ -74,10 +72,6 @@ public class AuthenticationManagerFactoryBean implements FactoryBean<Authenticat
}
provider.afterPropertiesSet();
ProviderManager manager = new ProviderManager(Arrays.asList(provider));
SecurityContextHolderStrategy securityContextHolderStrategy = this.bf
.getBeanProvider(SecurityContextHolderStrategy.class)
.getIfUnique(SecurityContextHolder::getContextHolderStrategy);
manager.setSecurityContextHolderStrategy(securityContextHolderStrategy);
if (this.observationRegistry.isNoop()) {
return manager;
}