Correctly configure authorization requests repository for OAuth2 login

To use custom ServerAuthorizationRequestRepository both OAuth2AuthorizationRequestRedirectWebFilter and
OAuth2LoginAuthenticationWebFilter should use the same repo provided in the configuration. Currently the former filter is
correctly configured, but the latter always uses default, WebSession based repository. So authorization code created
before redirect to authorization endpoint will never be found to complete OAuth2 login when custom
ServerAuthorizationRequestRepository is used.

This change also makes OAuth2Client and OAuth2Login authentication converters consistent.

Fixes gh-7675
This commit is contained in:
Alexey Nesterov 2019-11-26 10:14:25 +00:00 committed by Joe Grandja
parent 65513f2e3b
commit d8d59e97ac
2 changed files with 29 additions and 1 deletions

View File

@ -1084,7 +1084,9 @@ public class ServerHttpSecurity {
private ServerAuthenticationConverter getAuthenticationConverter(ReactiveClientRegistrationRepository clientRegistrationRepository) {
if (this.authenticationConverter == null) {
this.authenticationConverter = new ServerOAuth2AuthorizationCodeAuthenticationTokenConverter(clientRegistrationRepository);
ServerOAuth2AuthorizationCodeAuthenticationTokenConverter authenticationConverter = new ServerOAuth2AuthorizationCodeAuthenticationTokenConverter(clientRegistrationRepository);
authenticationConverter.setAuthorizationRequestRepository(getAuthorizationRequestRepository());
this.authenticationConverter = authenticationConverter;
}
return this.authenticationConverter;
}

View File

@ -39,6 +39,10 @@ import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.server.ServerAuthorizationRequestRepository;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
import org.springframework.security.oauth2.core.endpoint.TestOAuth2AuthorizationRequests;
import org.springframework.security.web.authentication.preauth.x509.X509PrincipalExtractor;
import org.springframework.security.web.server.authentication.ServerX509AuthenticationConverter;
import reactor.core.publisher.Mono;
@ -475,6 +479,28 @@ public class ServerHttpSecurityTests {
verify(customServerCsrfTokenRepository).loadToken(any());
}
@Test
public void shouldConfigureAuthorizationRequestRepositoryForOAuth2Login() {
ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository = mock(ServerAuthorizationRequestRepository.class);
ReactiveClientRegistrationRepository clientRegistrationRepository = mock(ReactiveClientRegistrationRepository.class);
OAuth2AuthorizationRequest authorizationRequest = TestOAuth2AuthorizationRequests.request().build();
when(authorizationRequestRepository.removeAuthorizationRequest(any())).thenReturn(Mono.just(authorizationRequest));
SecurityWebFilterChain securityFilterChain = this.http
.oauth2Login()
.clientRegistrationRepository(clientRegistrationRepository)
.authorizationRequestRepository(authorizationRequestRepository)
.and()
.build();
WebTestClient client = WebTestClientBuilder.bindToWebFilters(securityFilterChain).build();
client.get().uri("/login/oauth2/code/registration-id").exchange();
verify(authorizationRequestRepository).removeAuthorizationRequest(any());
}
private boolean isX509Filter(WebFilter filter) {
try {
Object converter = ReflectionTestUtils.getField(filter, "authenticationConverter");