Skip to content

Commit 46283b3

Browse files
fkowaljzheaux
authored andcommitted
Relax ObjectPostProcessor Type Constraints
Closes gh-17175 Signed-off-by: Maciej Kowalski <[email protected]>
1 parent fc66501 commit 46283b3

File tree

2 files changed

+78
-4
lines changed

2 files changed

+78
-4
lines changed

config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurer.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -404,11 +404,9 @@ public void init(B http) throws Exception {
404404
oidcAuthorizationCodeAuthenticationProvider.setAuthoritiesMapper(userAuthoritiesMapper);
405405
oidcAuthorizedClientRefreshedEventListener.setAuthoritiesMapper(userAuthoritiesMapper);
406406
}
407-
oidcAuthorizationCodeAuthenticationProvider = this.postProcess(oidcAuthorizationCodeAuthenticationProvider);
408-
http.authenticationProvider(oidcAuthorizationCodeAuthenticationProvider);
407+
http.authenticationProvider(this.postProcess(oidcAuthorizationCodeAuthenticationProvider));
409408

410-
oidcAuthorizedClientRefreshedEventListener = this.postProcess(oidcAuthorizedClientRefreshedEventListener);
411-
registerDelegateApplicationListener(oidcAuthorizedClientRefreshedEventListener);
409+
registerDelegateApplicationListener(this.postProcess(oidcAuthorizedClientRefreshedEventListener));
412410
configureOidcUserRefreshedEventListener(http);
413411
}
414412
else {

config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurerTests.java

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@
4343
import org.springframework.mock.web.MockFilterChain;
4444
import org.springframework.mock.web.MockHttpServletRequest;
4545
import org.springframework.mock.web.MockHttpServletResponse;
46+
import org.springframework.security.authentication.AuthenticationProvider;
4647
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
48+
import org.springframework.security.config.Customizer;
49+
import org.springframework.security.config.ObjectPostProcessor;
4750
import org.springframework.security.config.annotation.SecurityContextChangedListenerConfig;
4851
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
4952
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
@@ -52,6 +55,7 @@
5255
import org.springframework.security.config.test.SpringTestContextExtension;
5356
import org.springframework.security.context.DelegatingApplicationListener;
5457
import org.springframework.security.core.Authentication;
58+
import org.springframework.security.core.AuthenticationException;
5559
import org.springframework.security.core.GrantedAuthority;
5660
import org.springframework.security.core.authority.AuthorityUtils;
5761
import org.springframework.security.core.authority.SimpleGrantedAuthority;
@@ -214,6 +218,28 @@ public void oauth2Login() throws Exception {
214218
.hasToString("OAUTH2_USER");
215219
}
216220

221+
// gh-17175
222+
@Test
223+
public void postProcessorSucceedsWhenProcessorReturnsAuthenticationProvider() throws Exception {
224+
loadConfig(OAuth2LoginConfigCustomWithPostProcessor.class);
225+
// setup authorization request
226+
OAuth2AuthorizationRequest authorizationRequest = createOAuth2AuthorizationRequest();
227+
this.authorizationRequestRepository.saveAuthorizationRequest(authorizationRequest, this.request, this.response);
228+
// setup authentication parameters
229+
this.request.setParameter("code", "code123");
230+
this.request.setParameter("state", authorizationRequest.getState());
231+
// perform test
232+
this.springSecurityFilterChain.doFilter(this.request, this.response, this.filterChain);
233+
// assertions
234+
Authentication authentication = this.securityContextRepository
235+
.loadContext(new HttpRequestResponseHolder(this.request, this.response))
236+
.getAuthentication();
237+
assertThat(authentication.getAuthorities()).hasSize(1);
238+
assertThat(authentication.getAuthorities()).first()
239+
.isInstanceOf(OAuth2UserAuthority.class)
240+
.hasToString("OAUTH2_USER");
241+
}
242+
217243
@Test
218244
public void requestWhenCustomSecurityContextHolderStrategyThenUses() throws Exception {
219245
loadConfig(OAuth2LoginConfig.class, SecurityContextChangedListenerConfig.class);
@@ -1307,6 +1333,56 @@ OAuth2AuthorizedClientRepository authorizedClientRepository() {
13071333

13081334
}
13091335

1336+
@Configuration
1337+
@EnableWebSecurity
1338+
static class OAuth2LoginConfigCustomWithPostProcessor
1339+
extends CommonLambdaSecurityFilterChainConfig {
1340+
1341+
private ClientRegistrationRepository clientRegistrationRepository = new InMemoryClientRegistrationRepository(
1342+
GOOGLE_CLIENT_REGISTRATION);
1343+
1344+
OAuth2AuthorizationRequestResolver resolver = mock(OAuth2AuthorizationRequestResolver.class);
1345+
1346+
@Bean
1347+
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
1348+
// @formatter:off
1349+
http
1350+
.oauth2Login((oauth2Login) ->
1351+
oauth2Login
1352+
.clientRegistrationRepository(this.clientRegistrationRepository)
1353+
// .authorizedClientRepository(this.authorizedClientRepository)
1354+
.withObjectPostProcessor(new CustomProcessor())
1355+
);
1356+
// @formatter:on
1357+
return super.configureFilterChain(http);
1358+
}
1359+
1360+
class CustomProcessor implements ObjectPostProcessor<AuthenticationProvider> {
1361+
@Override
1362+
public <O extends AuthenticationProvider> O postProcess(O object) {
1363+
AuthenticationProvider p = new NoopWrapperProvider(object);
1364+
1365+
return (O) p;
1366+
}
1367+
}
1368+
1369+
record NoopWrapperProvider(
1370+
AuthenticationProvider delegate
1371+
) implements AuthenticationProvider {
1372+
1373+
@Override
1374+
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
1375+
return delegate.authenticate(authentication);
1376+
}
1377+
1378+
@Override
1379+
public boolean supports(Class<?> authentication) {
1380+
return delegate.supports(authentication);
1381+
}
1382+
}
1383+
1384+
}
1385+
13101386
private abstract static class CommonSecurityFilterChainConfig {
13111387

13121388
SecurityFilterChain configureFilterChain(HttpSecurity http) throws Exception {

0 commit comments

Comments
 (0)