Skip to content

Commit b48b10a

Browse files
committed
Pick Up SecurityContextHolderStrategy Bean
This commit provides the SecurityContextHolderStrategy bean to ProviderManager instances that the HttpSecurity DSL constructs.
1 parent 2524a07 commit b48b10a

File tree

6 files changed

+45
-2
lines changed

6 files changed

+45
-2
lines changed

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,14 @@
1818

1919
import java.util.ArrayList;
2020
import java.util.List;
21+
import java.util.stream.Stream;
2122

2223
import org.apache.commons.logging.Log;
2324
import org.apache.commons.logging.LogFactory;
25+
import org.jspecify.annotations.Nullable;
2426

27+
import org.springframework.beans.factory.BeanFactory;
28+
import org.springframework.beans.factory.ObjectProvider;
2529
import org.springframework.security.authentication.AuthenticationEventPublisher;
2630
import org.springframework.security.authentication.AuthenticationManager;
2731
import org.springframework.security.authentication.AuthenticationProvider;
@@ -37,6 +41,8 @@
3741
import org.springframework.security.config.annotation.authentication.configurers.userdetails.DaoAuthenticationConfigurer;
3842
import org.springframework.security.config.annotation.authentication.configurers.userdetails.UserDetailsAwareConfigurer;
3943
import org.springframework.security.core.Authentication;
44+
import org.springframework.security.core.context.SecurityContextHolder;
45+
import org.springframework.security.core.context.SecurityContextHolderStrategy;
4046
import org.springframework.security.core.userdetails.UserDetailsService;
4147
import org.springframework.util.Assert;
4248

@@ -235,6 +241,10 @@ protected ProviderManager performBuild() throws Exception {
235241
if (this.eventPublisher != null) {
236242
providerManager.setAuthenticationEventPublisher(this.eventPublisher);
237243
}
244+
SecurityContextHolderStrategy securityContextHolderStrategy = getBeanProvider(
245+
SecurityContextHolderStrategy.class)
246+
.getIfUnique(SecurityContextHolder::getContextHolderStrategy);
247+
providerManager.setSecurityContextHolderStrategy(securityContextHolderStrategy);
238248
providerManager = postProcess(providerManager);
239249
return providerManager;
240250
}
@@ -283,4 +293,24 @@ public UserDetailsService getDefaultUserDetailsService() {
283293
return configurer;
284294
}
285295

296+
private <C> ObjectProvider<C> getBeanProvider(Class<C> clazz) {
297+
BeanFactory beanFactory = getSharedObject(BeanFactory.class);
298+
return (beanFactory != null) ? beanFactory.getBeanProvider(clazz) : new SingleObjectProvider<>(null);
299+
}
300+
301+
private static final class SingleObjectProvider<O> implements ObjectProvider<O> {
302+
303+
private final @Nullable O object;
304+
305+
private SingleObjectProvider(@Nullable O object) {
306+
this.object = object;
307+
}
308+
309+
@Override
310+
public Stream<O> stream() {
311+
return Stream.ofNullable(this.object);
312+
}
313+
314+
}
315+
286316
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
import org.springframework.aop.framework.ProxyFactoryBean;
2929
import org.springframework.aop.target.LazyInitTargetSource;
30+
import org.springframework.beans.factory.BeanFactory;
3031
import org.springframework.beans.factory.BeanFactoryUtils;
3132
import org.springframework.beans.factory.annotation.Autowired;
3233
import org.springframework.context.ApplicationContext;
@@ -83,6 +84,7 @@ public AuthenticationManagerBuilder authenticationManagerBuilder(ObjectPostProce
8384
AuthenticationEventPublisher authenticationEventPublisher = getAuthenticationEventPublisher(context);
8485
DefaultPasswordEncoderAuthenticationManagerBuilder result = new DefaultPasswordEncoderAuthenticationManagerBuilder(
8586
objectPostProcessor, defaultPasswordEncoder);
87+
result.setSharedObject(BeanFactory.class, this.applicationContext);
8688
if (authenticationEventPublisher != null) {
8789
result.authenticationEventPublisher(authenticationEventPublisher);
8890
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ protected AuthenticationManager authenticationManager() throws Exception {
318318
.postProcess(new DefaultAuthenticationEventPublisher());
319319
this.auth = new AuthenticationManagerBuilder(this.objectPostProcessor);
320320
this.auth.authenticationEventPublisher(eventPublisher);
321+
this.auth.setSharedObject(BeanFactory.class, this.context);
321322
configure(this.auth);
322323
this.authenticationManager = (this.disableAuthenticationRegistry)
323324
? getAuthenticationConfiguration().getAuthenticationManager() : this.auth.build();

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.List;
2222
import java.util.Map;
2323

24+
import org.springframework.beans.factory.BeanFactory;
2425
import org.springframework.beans.factory.ObjectProvider;
2526
import org.springframework.beans.factory.annotation.Autowired;
2627
import org.springframework.context.ApplicationContext;
@@ -116,6 +117,7 @@ HttpSecurity httpSecurity() throws Exception {
116117
LazyPasswordEncoder passwordEncoder = new LazyPasswordEncoder(this.context);
117118
AuthenticationManagerBuilder authenticationBuilder = new DefaultPasswordEncoderAuthenticationManagerBuilder(
118119
this.objectPostProcessor, passwordEncoder);
120+
authenticationBuilder.setSharedObject(BeanFactory.class, this.context);
119121
authenticationBuilder.parentAuthenticationManager(authenticationManager());
120122
authenticationBuilder.authenticationEventPublisher(getAuthenticationEventPublisher());
121123
HttpSecurity http = new HttpSecurity(this.objectPostProcessor, authenticationBuilder, createSharedObjects());

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,10 @@ public void configure(H http) throws Exception {
162162
WebAuthnRelyingPartyOperations rpOperations = webAuthnRelyingPartyOperations(userEntities, userCredentials);
163163
PublicKeyCredentialCreationOptionsRepository creationOptionsRepository = creationOptionsRepository();
164164
WebAuthnAuthenticationFilter webAuthnAuthnFilter = new WebAuthnAuthenticationFilter();
165-
webAuthnAuthnFilter.setAuthenticationManager(
166-
new ProviderManager(new WebAuthnAuthenticationProvider(rpOperations, userDetailsService)));
165+
ProviderManager manager = new ProviderManager(
166+
new WebAuthnAuthenticationProvider(rpOperations, userDetailsService));
167+
manager.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
168+
webAuthnAuthnFilter.setAuthenticationManager(manager);
167169
WebAuthnRegistrationFilter webAuthnRegistrationFilter = new WebAuthnRegistrationFilter(userCredentials,
168170
rpOperations);
169171
PublicKeyCredentialCreationOptionsFilter creationOptionsFilter = new PublicKeyCredentialCreationOptionsFilter(

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import org.springframework.security.authentication.ProviderManager;
3131
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
3232
import org.springframework.security.config.BeanIds;
33+
import org.springframework.security.core.context.SecurityContextHolder;
34+
import org.springframework.security.core.context.SecurityContextHolderStrategy;
3335
import org.springframework.security.core.userdetails.UserDetailsService;
3436
import org.springframework.security.crypto.password.PasswordEncoder;
3537

@@ -72,6 +74,10 @@ public AuthenticationManager getObject() throws Exception {
7274
}
7375
provider.afterPropertiesSet();
7476
ProviderManager manager = new ProviderManager(Arrays.asList(provider));
77+
SecurityContextHolderStrategy securityContextHolderStrategy = this.bf
78+
.getBeanProvider(SecurityContextHolderStrategy.class)
79+
.getIfUnique(SecurityContextHolder::getContextHolderStrategy);
80+
manager.setSecurityContextHolderStrategy(securityContextHolderStrategy);
7581
if (this.observationRegistry.isNoop()) {
7682
return manager;
7783
}

0 commit comments

Comments
 (0)