Browse Source

Pick Up SecurityContextHolderStrategy Bean

This commit provides the SecurityContextHolderStrategy bean to
ProviderManager instances that the HttpSecurity DSL constructs.

Issue gh-17862
pull/17790/head
Josh Cummings 4 months ago
parent
commit
44fef786aa
  1. 30
      config/src/main/java/org/springframework/security/config/annotation/authentication/builders/AuthenticationManagerBuilder.java
  2. 2
      config/src/main/java/org/springframework/security/config/annotation/authentication/configuration/AuthenticationConfiguration.java
  3. 1
      config/src/main/java/org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.java
  4. 2
      config/src/main/java/org/springframework/security/config/annotation/web/configuration/HttpSecurityConfiguration.java
  5. 6
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/WebAuthnConfigurer.java
  6. 6
      config/src/main/java/org/springframework/security/config/authentication/AuthenticationManagerFactoryBean.java

30
config/src/main/java/org/springframework/security/config/annotation/authentication/builders/AuthenticationManagerBuilder.java

@ -18,10 +18,14 @@ package org.springframework.security.config.annotation.authentication.builders; @@ -18,10 +18,14 @@ 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;
@ -37,6 +41,8 @@ import org.springframework.security.config.annotation.authentication.configurers @@ -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.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;
@ -235,6 +241,10 @@ public class AuthenticationManagerBuilder @@ -235,6 +241,10 @@ 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;
}
@ -283,4 +293,24 @@ public class AuthenticationManagerBuilder @@ -283,4 +293,24 @@ 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);
}
}
}

2
config/src/main/java/org/springframework/security/config/annotation/authentication/configuration/AuthenticationConfiguration.java

@ -27,6 +27,7 @@ import org.apache.commons.logging.LogFactory; @@ -27,6 +27,7 @@ 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;
@ -83,6 +84,7 @@ public class AuthenticationConfiguration { @@ -83,6 +84,7 @@ 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);
}

1
config/src/main/java/org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.java

@ -318,6 +318,7 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit @@ -318,6 +318,7 @@ 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();

2
config/src/main/java/org/springframework/security/config/annotation/web/configuration/HttpSecurityConfiguration.java

@ -21,6 +21,7 @@ import java.util.HashMap; @@ -21,6 +21,7 @@ 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;
@ -116,6 +117,7 @@ class HttpSecurityConfiguration { @@ -116,6 +117,7 @@ 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());

6
config/src/main/java/org/springframework/security/config/annotation/web/configurers/WebAuthnConfigurer.java

@ -162,8 +162,10 @@ public class WebAuthnConfigurer<H extends HttpSecurityBuilder<H>> @@ -162,8 +162,10 @@ public class WebAuthnConfigurer<H extends HttpSecurityBuilder<H>>
WebAuthnRelyingPartyOperations rpOperations = webAuthnRelyingPartyOperations(userEntities, userCredentials);
PublicKeyCredentialCreationOptionsRepository creationOptionsRepository = creationOptionsRepository();
WebAuthnAuthenticationFilter webAuthnAuthnFilter = new WebAuthnAuthenticationFilter();
webAuthnAuthnFilter.setAuthenticationManager(
new ProviderManager(new WebAuthnAuthenticationProvider(rpOperations, userDetailsService)));
ProviderManager manager = new ProviderManager(
new WebAuthnAuthenticationProvider(rpOperations, userDetailsService));
manager.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
webAuthnAuthnFilter.setAuthenticationManager(manager);
WebAuthnRegistrationFilter webAuthnRegistrationFilter = new WebAuthnRegistrationFilter(userCredentials,
rpOperations);
PublicKeyCredentialCreationOptionsFilter creationOptionsFilter = new PublicKeyCredentialCreationOptionsFilter(

6
config/src/main/java/org/springframework/security/config/authentication/AuthenticationManagerFactoryBean.java

@ -30,6 +30,8 @@ import org.springframework.security.authentication.ObservationAuthenticationMana @@ -30,6 +30,8 @@ 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;
@ -72,6 +74,10 @@ public class AuthenticationManagerFactoryBean implements FactoryBean<Authenticat @@ -72,6 +74,10 @@ 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;
}

Loading…
Cancel
Save