|
29 | 29 | import org.junit.jupiter.api.BeforeEach;
|
30 | 30 | import org.junit.jupiter.api.Test;
|
31 | 31 | import org.junit.jupiter.api.extension.ExtendWith;
|
| 32 | +import org.mockito.Mockito; |
32 | 33 |
|
33 | 34 | import org.springframework.beans.factory.BeanCreationException;
|
34 | 35 | import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
|
|
43 | 44 | import org.springframework.mock.web.MockFilterChain;
|
44 | 45 | import org.springframework.mock.web.MockHttpServletRequest;
|
45 | 46 | import org.springframework.mock.web.MockHttpServletResponse;
|
| 47 | +import org.springframework.security.authentication.AuthenticationProvider; |
46 | 48 | import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
|
47 | 49 | import org.springframework.security.config.Customizer;
|
| 50 | +import org.springframework.security.config.ObjectPostProcessor; |
48 | 51 | import org.springframework.security.config.annotation.SecurityContextChangedListenerConfig;
|
49 | 52 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
50 | 53 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
| 54 | +import org.springframework.security.config.annotation.web.configurers.oauth2.client.OAuth2LoginConfigurerTests.OAuth2LoginConfigCustomWithPostProcessor.SpyObjectPostProcessor; |
51 | 55 | import org.springframework.security.config.oauth2.client.CommonOAuth2Provider;
|
52 | 56 | import org.springframework.security.config.test.SpringTestContext;
|
53 | 57 | import org.springframework.security.config.test.SpringTestContextExtension;
|
@@ -711,6 +715,22 @@ public void oidcLoginWhenOAuth2ClientBeansConfiguredThenNotShared() throws Excep
|
711 | 715 | verifyNoInteractions(clientRegistrationRepository, authorizedClientRepository);
|
712 | 716 | }
|
713 | 717 |
|
| 718 | + // gh-17175 |
| 719 | + @Test |
| 720 | + public void oauth2LoginWhenAuthenticationProviderPostProcessorThenUses() throws Exception { |
| 721 | + loadConfig(OAuth2LoginConfigCustomWithPostProcessor.class); |
| 722 | + // setup authorization request |
| 723 | + OAuth2AuthorizationRequest authorizationRequest = createOAuth2AuthorizationRequest(); |
| 724 | + this.authorizationRequestRepository.saveAuthorizationRequest(authorizationRequest, this.request, this.response); |
| 725 | + // setup authentication parameters |
| 726 | + this.request.setParameter("code", "code123"); |
| 727 | + this.request.setParameter("state", authorizationRequest.getState()); |
| 728 | + // perform test |
| 729 | + this.springSecurityFilterChain.doFilter(this.request, this.response, this.filterChain); |
| 730 | + // assertions |
| 731 | + verify(this.context.getBean(SpyObjectPostProcessor.class).spy).authenticate(any()); |
| 732 | + } |
| 733 | + |
714 | 734 | private void loadConfig(Class<?>... configs) {
|
715 | 735 | AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
|
716 | 736 | applicationContext.register(configs);
|
@@ -1296,6 +1316,52 @@ OAuth2AuthorizedClientRepository authorizedClientRepository() {
|
1296 | 1316 |
|
1297 | 1317 | }
|
1298 | 1318 |
|
| 1319 | + @Configuration |
| 1320 | + @EnableWebSecurity |
| 1321 | + static class OAuth2LoginConfigCustomWithPostProcessor { |
| 1322 | + |
| 1323 | + private final ClientRegistrationRepository clientRegistrationRepository = new InMemoryClientRegistrationRepository( |
| 1324 | + GOOGLE_CLIENT_REGISTRATION); |
| 1325 | + |
| 1326 | + private final ObjectPostProcessor<AuthenticationProvider> postProcessor = new SpyObjectPostProcessor(); |
| 1327 | + |
| 1328 | + @Bean |
| 1329 | + SecurityFilterChain filterChain(HttpSecurity http) throws Exception { |
| 1330 | + // @formatter:off |
| 1331 | + http |
| 1332 | + .oauth2Login((oauth2Login) -> oauth2Login |
| 1333 | + .clientRegistrationRepository(this.clientRegistrationRepository) |
| 1334 | + .withObjectPostProcessor(this.postProcessor) |
| 1335 | + ); |
| 1336 | + // @formatter:on |
| 1337 | + return http.build(); |
| 1338 | + } |
| 1339 | + |
| 1340 | + @Bean |
| 1341 | + ObjectPostProcessor<AuthenticationProvider> mockPostProcessor() { |
| 1342 | + return this.postProcessor; |
| 1343 | + } |
| 1344 | + |
| 1345 | + @Bean |
| 1346 | + HttpSessionOAuth2AuthorizationRequestRepository oauth2AuthorizationRequestRepository() { |
| 1347 | + return new HttpSessionOAuth2AuthorizationRequestRepository(); |
| 1348 | + } |
| 1349 | + |
| 1350 | + static class SpyObjectPostProcessor implements ObjectPostProcessor<AuthenticationProvider> { |
| 1351 | + |
| 1352 | + AuthenticationProvider spy; |
| 1353 | + |
| 1354 | + @Override |
| 1355 | + public <O extends AuthenticationProvider> O postProcess(O object) { |
| 1356 | + O spy = Mockito.spy(object); |
| 1357 | + this.spy = spy; |
| 1358 | + return spy; |
| 1359 | + } |
| 1360 | + |
| 1361 | + } |
| 1362 | + |
| 1363 | + } |
| 1364 | + |
1299 | 1365 | private abstract static class CommonSecurityFilterChainConfig {
|
1300 | 1366 |
|
1301 | 1367 | SecurityFilterChain configureFilterChain(HttpSecurity http) throws Exception {
|
|
0 commit comments