Pick Up SecurityContextHolderStrategy Bean
This commit provides the SecurityContextHolderStrategy bean to ProviderManager instances that the HttpSecurity DSL constructs. Issue gh-17862
This commit is contained in:
parent
8468c6a805
commit
44fef786aa
|
|
@ -18,10 +18,14 @@ package org.springframework.security.config.annotation.authentication.builders;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
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.AuthenticationEventPublisher;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.authentication.AuthenticationProvider;
|
import org.springframework.security.authentication.AuthenticationProvider;
|
||||||
|
|
@ -37,6 +41,8 @@ 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.DaoAuthenticationConfigurer;
|
||||||
import org.springframework.security.config.annotation.authentication.configurers.userdetails.UserDetailsAwareConfigurer;
|
import org.springframework.security.config.annotation.authentication.configurers.userdetails.UserDetailsAwareConfigurer;
|
||||||
import org.springframework.security.core.Authentication;
|
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.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
|
@ -235,6 +241,10 @@ public class AuthenticationManagerBuilder
|
||||||
if (this.eventPublisher != null) {
|
if (this.eventPublisher != null) {
|
||||||
providerManager.setAuthenticationEventPublisher(this.eventPublisher);
|
providerManager.setAuthenticationEventPublisher(this.eventPublisher);
|
||||||
}
|
}
|
||||||
|
SecurityContextHolderStrategy securityContextHolderStrategy = getBeanProvider(
|
||||||
|
SecurityContextHolderStrategy.class)
|
||||||
|
.getIfUnique(SecurityContextHolder::getContextHolderStrategy);
|
||||||
|
providerManager.setSecurityContextHolderStrategy(securityContextHolderStrategy);
|
||||||
providerManager = postProcess(providerManager);
|
providerManager = postProcess(providerManager);
|
||||||
return providerManager;
|
return providerManager;
|
||||||
}
|
}
|
||||||
|
|
@ -283,4 +293,24 @@ public class AuthenticationManagerBuilder
|
||||||
return configurer;
|
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,6 +27,7 @@ import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.aop.framework.ProxyFactoryBean;
|
import org.springframework.aop.framework.ProxyFactoryBean;
|
||||||
import org.springframework.aop.target.LazyInitTargetSource;
|
import org.springframework.aop.target.LazyInitTargetSource;
|
||||||
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
@ -83,6 +84,7 @@ public class AuthenticationConfiguration {
|
||||||
AuthenticationEventPublisher authenticationEventPublisher = getAuthenticationEventPublisher(context);
|
AuthenticationEventPublisher authenticationEventPublisher = getAuthenticationEventPublisher(context);
|
||||||
DefaultPasswordEncoderAuthenticationManagerBuilder result = new DefaultPasswordEncoderAuthenticationManagerBuilder(
|
DefaultPasswordEncoderAuthenticationManagerBuilder result = new DefaultPasswordEncoderAuthenticationManagerBuilder(
|
||||||
objectPostProcessor, defaultPasswordEncoder);
|
objectPostProcessor, defaultPasswordEncoder);
|
||||||
|
result.setSharedObject(BeanFactory.class, this.applicationContext);
|
||||||
if (authenticationEventPublisher != null) {
|
if (authenticationEventPublisher != null) {
|
||||||
result.authenticationEventPublisher(authenticationEventPublisher);
|
result.authenticationEventPublisher(authenticationEventPublisher);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -318,6 +318,7 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
|
||||||
.postProcess(new DefaultAuthenticationEventPublisher());
|
.postProcess(new DefaultAuthenticationEventPublisher());
|
||||||
this.auth = new AuthenticationManagerBuilder(this.objectPostProcessor);
|
this.auth = new AuthenticationManagerBuilder(this.objectPostProcessor);
|
||||||
this.auth.authenticationEventPublisher(eventPublisher);
|
this.auth.authenticationEventPublisher(eventPublisher);
|
||||||
|
this.auth.setSharedObject(BeanFactory.class, this.context);
|
||||||
configure(this.auth);
|
configure(this.auth);
|
||||||
this.authenticationManager = (this.disableAuthenticationRegistry)
|
this.authenticationManager = (this.disableAuthenticationRegistry)
|
||||||
? getAuthenticationConfiguration().getAuthenticationManager() : this.auth.build();
|
? getAuthenticationConfiguration().getAuthenticationManager() : this.auth.build();
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
@ -116,6 +117,7 @@ class HttpSecurityConfiguration {
|
||||||
LazyPasswordEncoder passwordEncoder = new LazyPasswordEncoder(this.context);
|
LazyPasswordEncoder passwordEncoder = new LazyPasswordEncoder(this.context);
|
||||||
AuthenticationManagerBuilder authenticationBuilder = new DefaultPasswordEncoderAuthenticationManagerBuilder(
|
AuthenticationManagerBuilder authenticationBuilder = new DefaultPasswordEncoderAuthenticationManagerBuilder(
|
||||||
this.objectPostProcessor, passwordEncoder);
|
this.objectPostProcessor, passwordEncoder);
|
||||||
|
authenticationBuilder.setSharedObject(BeanFactory.class, this.context);
|
||||||
authenticationBuilder.parentAuthenticationManager(authenticationManager());
|
authenticationBuilder.parentAuthenticationManager(authenticationManager());
|
||||||
authenticationBuilder.authenticationEventPublisher(getAuthenticationEventPublisher());
|
authenticationBuilder.authenticationEventPublisher(getAuthenticationEventPublisher());
|
||||||
HttpSecurity http = new HttpSecurity(this.objectPostProcessor, authenticationBuilder, createSharedObjects());
|
HttpSecurity http = new HttpSecurity(this.objectPostProcessor, authenticationBuilder, createSharedObjects());
|
||||||
|
|
|
||||||
|
|
@ -162,8 +162,10 @@ public class WebAuthnConfigurer<H extends HttpSecurityBuilder<H>>
|
||||||
WebAuthnRelyingPartyOperations rpOperations = webAuthnRelyingPartyOperations(userEntities, userCredentials);
|
WebAuthnRelyingPartyOperations rpOperations = webAuthnRelyingPartyOperations(userEntities, userCredentials);
|
||||||
PublicKeyCredentialCreationOptionsRepository creationOptionsRepository = creationOptionsRepository();
|
PublicKeyCredentialCreationOptionsRepository creationOptionsRepository = creationOptionsRepository();
|
||||||
WebAuthnAuthenticationFilter webAuthnAuthnFilter = new WebAuthnAuthenticationFilter();
|
WebAuthnAuthenticationFilter webAuthnAuthnFilter = new WebAuthnAuthenticationFilter();
|
||||||
webAuthnAuthnFilter.setAuthenticationManager(
|
ProviderManager manager = new ProviderManager(
|
||||||
new ProviderManager(new WebAuthnAuthenticationProvider(rpOperations, userDetailsService)));
|
new WebAuthnAuthenticationProvider(rpOperations, userDetailsService));
|
||||||
|
manager.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
|
||||||
|
webAuthnAuthnFilter.setAuthenticationManager(manager);
|
||||||
WebAuthnRegistrationFilter webAuthnRegistrationFilter = new WebAuthnRegistrationFilter(userCredentials,
|
WebAuthnRegistrationFilter webAuthnRegistrationFilter = new WebAuthnRegistrationFilter(userCredentials,
|
||||||
rpOperations);
|
rpOperations);
|
||||||
PublicKeyCredentialCreationOptionsFilter creationOptionsFilter = new PublicKeyCredentialCreationOptionsFilter(
|
PublicKeyCredentialCreationOptionsFilter creationOptionsFilter = new PublicKeyCredentialCreationOptionsFilter(
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@ import org.springframework.security.authentication.ObservationAuthenticationMana
|
||||||
import org.springframework.security.authentication.ProviderManager;
|
import org.springframework.security.authentication.ProviderManager;
|
||||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||||
import org.springframework.security.config.BeanIds;
|
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.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
|
||||||
|
|
@ -72,6 +74,10 @@ public class AuthenticationManagerFactoryBean implements FactoryBean<Authenticat
|
||||||
}
|
}
|
||||||
provider.afterPropertiesSet();
|
provider.afterPropertiesSet();
|
||||||
ProviderManager manager = new ProviderManager(Arrays.asList(provider));
|
ProviderManager manager = new ProviderManager(Arrays.asList(provider));
|
||||||
|
SecurityContextHolderStrategy securityContextHolderStrategy = this.bf
|
||||||
|
.getBeanProvider(SecurityContextHolderStrategy.class)
|
||||||
|
.getIfUnique(SecurityContextHolder::getContextHolderStrategy);
|
||||||
|
manager.setSecurityContextHolderStrategy(securityContextHolderStrategy);
|
||||||
if (this.observationRegistry.isNoop()) {
|
if (this.observationRegistry.isNoop()) {
|
||||||
return manager;
|
return manager;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue