|
28 | 28 | import org.junit.jupiter.api.BeforeEach;
|
29 | 29 | import org.junit.jupiter.api.Test;
|
30 | 30 | import org.junit.jupiter.api.extension.ExtendWith;
|
| 31 | +import org.mockito.ArgumentCaptor; |
31 | 32 |
|
32 | 33 | import org.springframework.beans.factory.BeanCreationException;
|
33 | 34 | import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
|
|
49 | 50 | import org.springframework.security.config.test.SpringTestContext;
|
50 | 51 | import org.springframework.security.config.test.SpringTestContextExtension;
|
51 | 52 | import org.springframework.security.core.Authentication;
|
| 53 | +import org.springframework.security.core.AuthenticationException; |
52 | 54 | import org.springframework.security.core.GrantedAuthority;
|
53 | 55 | import org.springframework.security.core.authority.AuthorityUtils;
|
54 | 56 | import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|
68 | 70 | import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
|
69 | 71 | import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository;
|
70 | 72 | import org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizationRequestRepository;
|
| 73 | +import org.springframework.security.oauth2.client.web.InvalidClientRegistrationIdException; |
71 | 74 | import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver;
|
72 | 75 | import org.springframework.security.oauth2.core.OAuth2AccessToken;
|
73 | 76 | import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
|
|
91 | 94 | import org.springframework.security.web.FilterChainProxy;
|
92 | 95 | import org.springframework.security.web.RedirectStrategy;
|
93 | 96 | import org.springframework.security.web.SecurityFilterChain;
|
| 97 | +import org.springframework.security.web.authentication.AuthenticationFailureHandler; |
94 | 98 | import org.springframework.security.web.authentication.HttpStatusEntryPoint;
|
95 | 99 | import org.springframework.security.web.context.HttpRequestResponseHolder;
|
96 | 100 | import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
|
@@ -537,6 +541,23 @@ public void requestWhenOauth2LoginWithCustomLoginPageInLambdaThenRedirectCustomL
|
537 | 541 | assertThat(this.response.getRedirectedUrl()).matches("http://localhost/custom-login");
|
538 | 542 | }
|
539 | 543 |
|
| 544 | + // gh-13793 |
| 545 | + @Test |
| 546 | + public void oauth2LoginWithCustomAuthenticationFailureHandlerThenUsedWithInvalidClientRegistrationIdException() |
| 547 | + throws Exception { |
| 548 | + loadConfig(OAuth2LoginConfigCustomAuthenticationFailureHandler.class); |
| 549 | + AuthenticationFailureHandler authenticationFailureHandler = this.context |
| 550 | + .getBean(OAuth2LoginConfigCustomAuthenticationFailureHandler.class).authenticationFailureHandler; |
| 551 | + String requestUri = "/oauth2/authorization/invalid-client-registration-id"; |
| 552 | + this.request = new MockHttpServletRequest("GET", requestUri); |
| 553 | + this.request.setServletPath(requestUri); |
| 554 | + this.springSecurityFilterChain.doFilter(this.request, this.response, this.filterChain); |
| 555 | + |
| 556 | + ArgumentCaptor<AuthenticationException> capture = ArgumentCaptor.forClass(AuthenticationException.class); |
| 557 | + then(authenticationFailureHandler).should().onAuthenticationFailure(any(), any(), capture.capture()); |
| 558 | + assertThat(capture.getValue()).hasCauseInstanceOf(InvalidClientRegistrationIdException.class); |
| 559 | + } |
| 560 | + |
540 | 561 | @Test
|
541 | 562 | public void oidcLogin() throws Exception {
|
542 | 563 | // setup application context
|
@@ -1069,6 +1090,29 @@ SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
1069 | 1090 |
|
1070 | 1091 | }
|
1071 | 1092 |
|
| 1093 | + @Configuration |
| 1094 | + @EnableWebSecurity |
| 1095 | + static class OAuth2LoginConfigCustomAuthenticationFailureHandler extends CommonSecurityFilterChainConfig { |
| 1096 | + |
| 1097 | + AuthenticationFailureHandler authenticationFailureHandler = mock(AuthenticationFailureHandler.class); |
| 1098 | + |
| 1099 | + @Bean |
| 1100 | + SecurityFilterChain filterChain(HttpSecurity http) throws Exception { |
| 1101 | + // @formatter:off |
| 1102 | + http |
| 1103 | + .oauth2Login() |
| 1104 | + .clientRegistrationRepository( |
| 1105 | + new InMemoryClientRegistrationRepository(GOOGLE_CLIENT_REGISTRATION)) |
| 1106 | + .authorizationEndpoint((authorizationEndpoint) -> |
| 1107 | + authorizationEndpoint |
| 1108 | + .authenticationFailureHandler(this.authenticationFailureHandler) |
| 1109 | + ); |
| 1110 | + // @formatter:on |
| 1111 | + return super.configureFilterChain(http); |
| 1112 | + } |
| 1113 | + |
| 1114 | + } |
| 1115 | + |
1072 | 1116 | @Configuration
|
1073 | 1117 | @EnableWebSecurity
|
1074 | 1118 | static class OAuth2LoginConfigWithOidcLogoutSuccessHandler extends CommonSecurityFilterChainConfig {
|
|
0 commit comments