Skip to content

Commit 41398f0

Browse files
committed
Move Authority Propagation Into Filters
1 parent d46ce34 commit 41398f0

File tree

17 files changed

+55
-139
lines changed

17 files changed

+55
-139
lines changed

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

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

1919
import java.util.ArrayList;
2020
import java.util.List;
21-
import java.util.stream.Stream;
2221

2322
import org.apache.commons.logging.Log;
2423
import org.apache.commons.logging.LogFactory;
25-
import org.jspecify.annotations.Nullable;
2624

27-
import org.springframework.beans.factory.BeanFactory;
28-
import org.springframework.beans.factory.ObjectProvider;
2925
import org.springframework.security.authentication.AuthenticationEventPublisher;
3026
import org.springframework.security.authentication.AuthenticationManager;
3127
import org.springframework.security.authentication.AuthenticationProvider;
@@ -41,8 +37,6 @@
4137
import org.springframework.security.config.annotation.authentication.configurers.userdetails.DaoAuthenticationConfigurer;
4238
import org.springframework.security.config.annotation.authentication.configurers.userdetails.UserDetailsAwareConfigurer;
4339
import org.springframework.security.core.Authentication;
44-
import org.springframework.security.core.context.SecurityContextHolder;
45-
import org.springframework.security.core.context.SecurityContextHolderStrategy;
4640
import org.springframework.security.core.userdetails.UserDetailsService;
4741
import org.springframework.util.Assert;
4842

@@ -241,10 +235,6 @@ protected ProviderManager performBuild() throws Exception {
241235
if (this.eventPublisher != null) {
242236
providerManager.setAuthenticationEventPublisher(this.eventPublisher);
243237
}
244-
SecurityContextHolderStrategy securityContextHolderStrategy = getBeanProvider(
245-
SecurityContextHolderStrategy.class)
246-
.getIfUnique(SecurityContextHolder::getContextHolderStrategy);
247-
providerManager.setSecurityContextHolderStrategy(securityContextHolderStrategy);
248238
providerManager = postProcess(providerManager);
249239
return providerManager;
250240
}
@@ -293,24 +283,4 @@ public UserDetailsService getDefaultUserDetailsService() {
293283
return configurer;
294284
}
295285

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-
316286
}

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

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

2828
import org.springframework.aop.framework.ProxyFactoryBean;
2929
import org.springframework.aop.target.LazyInitTargetSource;
30-
import org.springframework.beans.factory.BeanFactory;
3130
import org.springframework.beans.factory.BeanFactoryUtils;
3231
import org.springframework.beans.factory.annotation.Autowired;
3332
import org.springframework.context.ApplicationContext;
@@ -84,7 +83,6 @@ public AuthenticationManagerBuilder authenticationManagerBuilder(ObjectPostProce
8483
AuthenticationEventPublisher authenticationEventPublisher = getAuthenticationEventPublisher(context);
8584
DefaultPasswordEncoderAuthenticationManagerBuilder result = new DefaultPasswordEncoderAuthenticationManagerBuilder(
8685
objectPostProcessor, defaultPasswordEncoder);
87-
result.setSharedObject(BeanFactory.class, this.applicationContext);
8886
if (authenticationEventPublisher != null) {
8987
result.authenticationEventPublisher(authenticationEventPublisher);
9088
}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,6 @@ 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);
322321
configure(this.auth);
323322
this.authenticationManager = (this.disableAuthenticationRegistry)
324323
? getAuthenticationConfiguration().getAuthenticationManager() : this.auth.build();

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

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

24-
import org.springframework.beans.factory.BeanFactory;
2524
import org.springframework.beans.factory.ObjectProvider;
2625
import org.springframework.beans.factory.annotation.Autowired;
2726
import org.springframework.context.ApplicationContext;
@@ -117,7 +116,6 @@ HttpSecurity httpSecurity() throws Exception {
117116
LazyPasswordEncoder passwordEncoder = new LazyPasswordEncoder(this.context);
118117
AuthenticationManagerBuilder authenticationBuilder = new DefaultPasswordEncoderAuthenticationManagerBuilder(
119118
this.objectPostProcessor, passwordEncoder);
120-
authenticationBuilder.setSharedObject(BeanFactory.class, this.context);
121119
authenticationBuilder.parentAuthenticationManager(authenticationManager());
122120
authenticationBuilder.authenticationEventPublisher(getAuthenticationEventPublisher());
123121
HttpSecurity http = new HttpSecurity(this.objectPostProcessor, authenticationBuilder, createSharedObjects());

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

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

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
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;
3533
import org.springframework.security.core.userdetails.UserDetailsService;
3634
import org.springframework.security.crypto.password.PasswordEncoder;
3735

@@ -74,10 +72,6 @@ public AuthenticationManager getObject() throws Exception {
7472
}
7573
provider.afterPropertiesSet();
7674
ProviderManager manager = new ProviderManager(Arrays.asList(provider));
77-
SecurityContextHolderStrategy securityContextHolderStrategy = this.bf
78-
.getBeanProvider(SecurityContextHolderStrategy.class)
79-
.getIfUnique(SecurityContextHolder::getContextHolderStrategy);
80-
manager.setSecurityContextHolderStrategy(securityContextHolderStrategy);
8175
if (this.observationRegistry.isNoop()) {
8276
return manager;
8377
}

core/src/main/java/org/springframework/security/authentication/AbstractAuthenticationToken.java

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

1717
package org.springframework.security.authentication;
1818

19+
import java.io.Serial;
1920
import java.security.Principal;
2021
import java.util.ArrayList;
2122
import java.util.Collection;
@@ -43,6 +44,7 @@
4344
*/
4445
public abstract class AbstractAuthenticationToken implements Authentication, CredentialsContainer {
4546

47+
@Serial
4648
private static final long serialVersionUID = -3194696462184782834L;
4749

4850
private final Collection<GrantedAuthority> authorities;

core/src/main/java/org/springframework/security/authentication/DelegatingReactiveAuthenticationManager.java

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

2828
import org.springframework.security.core.Authentication;
2929
import org.springframework.security.core.AuthenticationException;
30-
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
3130
import org.springframework.util.Assert;
3231

3332
/**
@@ -58,20 +57,6 @@ public DelegatingReactiveAuthenticationManager(List<ReactiveAuthenticationManage
5857

5958
@Override
6059
public Mono<Authentication> authenticate(Authentication authentication) {
61-
return ReactiveSecurityContextHolder.getContext().flatMap((context) -> {
62-
Mono<Authentication> result = doAuthenticate(authentication);
63-
Authentication current = context.getAuthentication();
64-
if (current == null) {
65-
return result;
66-
}
67-
if (!current.isAuthenticated()) {
68-
return result;
69-
}
70-
return doAuthenticate(current).map((r) -> r.toBuilder().apply(current).build());
71-
}).switchIfEmpty(doAuthenticate(authentication));
72-
}
73-
74-
private Mono<Authentication> doAuthenticate(Authentication authentication) {
7560
Flux<ReactiveAuthenticationManager> result = Flux.fromIterable(this.delegates);
7661
Function<ReactiveAuthenticationManager, Mono<Authentication>> logging = (m) -> m.authenticate(authentication)
7762
.doOnError(AuthenticationException.class, (ex) -> ex.setAuthenticationRequest(authentication))

core/src/main/java/org/springframework/security/authentication/ProviderManager.java

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@
3333
import org.springframework.security.core.AuthenticationException;
3434
import org.springframework.security.core.CredentialsContainer;
3535
import org.springframework.security.core.SpringSecurityMessageSource;
36-
import org.springframework.security.core.context.SecurityContextHolder;
37-
import org.springframework.security.core.context.SecurityContextHolderStrategy;
3836
import org.springframework.util.Assert;
3937
import org.springframework.util.CollectionUtils;
4038

@@ -94,9 +92,6 @@ public class ProviderManager implements AuthenticationManager, MessageSourceAwar
9492

9593
private static final Log logger = LogFactory.getLog(ProviderManager.class);
9694

97-
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
98-
.getContextHolderStrategy();
99-
10095
private AuthenticationEventPublisher eventPublisher = new NullEventPublisher();
10196

10297
private List<AuthenticationProvider> providers = Collections.emptyList();
@@ -187,7 +182,7 @@ public Authentication authenticate(Authentication authentication) throws Authent
187182
try {
188183
result = provider.authenticate(authentication);
189184
if (result != null) {
190-
copyDetails(authentication, result);
185+
result = copyDetails(authentication, result);
191186
break;
192187
}
193188
}
@@ -214,7 +209,6 @@ public Authentication authenticate(Authentication authentication) throws Authent
214209
lastException = ex;
215210
}
216211
}
217-
result = applyPreviousAuthentication(result);
218212
if (result == null && this.parent != null) {
219213
// Allow the parent to try.
220214
try {
@@ -271,20 +265,6 @@ public Authentication authenticate(Authentication authentication) throws Authent
271265
throw lastException;
272266
}
273267

274-
private @Nullable Authentication applyPreviousAuthentication(@Nullable Authentication result) {
275-
if (result == null) {
276-
return null;
277-
}
278-
Authentication current = this.securityContextHolderStrategy.getContext().getAuthentication();
279-
if (current == null) {
280-
return result;
281-
}
282-
if (!current.isAuthenticated()) {
283-
return result;
284-
}
285-
return result.toBuilder().apply(current).build();
286-
}
287-
288268
@SuppressWarnings("deprecation")
289269
private void prepareException(AuthenticationException ex, Authentication auth) {
290270
ex.setAuthenticationRequest(auth);
@@ -297,21 +277,14 @@ private void prepareException(AuthenticationException ex, Authentication auth) {
297277
* @param source source authentication
298278
* @param dest the destination authentication object
299279
*/
300-
private void copyDetails(Authentication source, Authentication dest) {
301-
if ((dest instanceof AbstractAuthenticationToken token) && (dest.getDetails() == null)) {
302-
token.setDetails(source.getDetails());
303-
}
280+
private Authentication copyDetails(Authentication source, Authentication dest) {
281+
return (dest.getDetails() != null) ? dest : dest.toBuilder().details(source.getDetails()).build();
304282
}
305283

306284
public List<AuthenticationProvider> getProviders() {
307285
return this.providers;
308286
}
309287

310-
public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {
311-
Assert.notNull(securityContextHolderStrategy, "securityContextHolderStrategy cannot be null");
312-
this.securityContextHolderStrategy = securityContextHolderStrategy;
313-
}
314-
315288
@Override
316289
public void setMessageSource(MessageSource messageSource) {
317290
this.messages = new MessageSourceAccessor(messageSource);

core/src/test/java/org/springframework/security/authentication/DelegatingReactiveAuthenticationManagerTests.java

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,10 @@
2727

2828
import org.springframework.security.core.Authentication;
2929
import org.springframework.security.core.AuthenticationException;
30-
import org.springframework.security.core.GrantedAuthority;
31-
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
3230

3331
import static org.assertj.core.api.Assertions.assertThat;
3432
import static org.mockito.ArgumentMatchers.any;
3533
import static org.mockito.BDDMockito.given;
36-
import static org.mockito.Mockito.mock;
3734

3835
/**
3936
* @author Rob Winch
@@ -121,24 +118,6 @@ void whenAccountStatusExceptionThenAuthenticationRequestIsIncluded() {
121118
assertThat(expected.getAuthenticationRequest()).isEqualTo(this.authentication);
122119
}
123120

124-
@Test
125-
void authenticateWhenPreviousAuthenticationThenApplies() {
126-
Authentication factorOne = new TestingAuthenticationToken("user", "pass", "FACTOR_ONE");
127-
Authentication factorTwo = new TestingAuthenticationToken("user", "pass", "FACTOR_TWO");
128-
ReactiveAuthenticationManager provider = mock(ReactiveAuthenticationManager.class);
129-
given(provider.authenticate(any())).willReturn(Mono.just(factorTwo));
130-
ReactiveAuthenticationManager manager = new DelegatingReactiveAuthenticationManager(provider);
131-
Authentication request = new TestingAuthenticationToken("user", "password");
132-
StepVerifier
133-
.create(manager.authenticate(request)
134-
.flatMapIterable(Authentication::getAuthorities)
135-
.map(GrantedAuthority::getAuthority)
136-
.contextWrite(ReactiveSecurityContextHolder.withAuthentication(factorOne)))
137-
.expectNext("FACTOR_TWO")
138-
.expectNext("FACTOR_ONE")
139-
.verifyComplete();
140-
}
141-
142121
private DelegatingReactiveAuthenticationManager managerWithContinueOnError() {
143122
DelegatingReactiveAuthenticationManager manager = new DelegatingReactiveAuthenticationManager(this.delegate1,
144123
this.delegate2);

0 commit comments

Comments
 (0)