diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/DefaultServerOAuth2AuthorizationRequestResolver.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/DefaultServerOAuth2AuthorizationRequestResolver.java new file mode 100644 index 0000000000..a72a18c1be --- /dev/null +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/DefaultServerOAuth2AuthorizationRequestResolver.java @@ -0,0 +1,168 @@ +/* + * Copyright 2002-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.security.oauth2.client.web.server; + +import org.springframework.http.HttpStatus; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.http.server.reactive.ServerHttpRequestDecorator; +import org.springframework.security.crypto.keygen.Base64StringKeyGenerator; +import org.springframework.security.crypto.keygen.StringKeyGenerator; +import org.springframework.security.oauth2.client.registration.ClientRegistration; +import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; +import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; +import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; +import org.springframework.security.web.server.util.matcher.PathPatternParserServerWebExchangeMatcher; +import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; +import org.springframework.util.Assert; +import org.springframework.web.server.ResponseStatusException; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.util.UriComponentsBuilder; +import reactor.core.publisher.Mono; + +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; + +/** + * The default implementation of {@link ServerOAuth2AuthorizationRequestResolver}. + * + * The {@link ClientRegistration#getRegistrationId()} is extracted from the request using the + * {@link #DEFAULT_AUTHORIZATION_REQUEST_PATTERN}. The injected {@link ReactiveClientRegistrationRepository} is then + * used to resolve the {@link ClientRegistration} and create the {@link OAuth2AuthorizationRequest}. + * + * @author Rob Winch + * @since 5.1 + */ +public class DefaultServerOAuth2AuthorizationRequestResolver + implements ServerOAuth2AuthorizationRequestResolver { + + /** + * The name of the path variable that contains the {@link ClientRegistration#getRegistrationId()} + */ + public static final String DEFAULT_REGISTRATION_ID_URI_VARIABLE_NAME = "registrationId"; + + /** + * The default pattern used to resolve the {@link ClientRegistration#getRegistrationId()} + */ + public static final String DEFAULT_AUTHORIZATION_REQUEST_PATTERN = "/oauth2/authorization/{" + DEFAULT_REGISTRATION_ID_URI_VARIABLE_NAME + + "}"; + + private final ServerWebExchangeMatcher authorizationRequestMatcher; + + private final ReactiveClientRegistrationRepository clientRegistrationRepository; + + private final StringKeyGenerator stateGenerator = new Base64StringKeyGenerator(Base64.getUrlEncoder()); + + /** + * Creates a new instance + * @param clientRegistrationRepository the repository to resolve the {@link ClientRegistration} + */ + public DefaultServerOAuth2AuthorizationRequestResolver(ReactiveClientRegistrationRepository clientRegistrationRepository) { + this(clientRegistrationRepository, new PathPatternParserServerWebExchangeMatcher( + DEFAULT_AUTHORIZATION_REQUEST_PATTERN)); + } + + /** + * Creates a new instance + * @param clientRegistrationRepository the repository to resolve the {@link ClientRegistration} + * @param authorizationRequestMatcher the matcher that determines if the request is a match and extracts the + * {@link #DEFAULT_REGISTRATION_ID_URI_VARIABLE_NAME} from the path variables. + */ + public DefaultServerOAuth2AuthorizationRequestResolver(ReactiveClientRegistrationRepository clientRegistrationRepository, + ServerWebExchangeMatcher authorizationRequestMatcher) { + Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null"); + Assert.notNull(authorizationRequestMatcher, "authorizationRequestMatcher cannot be null"); + this.clientRegistrationRepository = clientRegistrationRepository; + this.authorizationRequestMatcher = authorizationRequestMatcher; + } + + @Override + public Mono resolve(ServerWebExchange exchange) { + return this.authorizationRequestMatcher.matches(exchange) + .filter(matchResult -> matchResult.isMatch()) + .map(ServerWebExchangeMatcher.MatchResult::getVariables) + .map(variables -> variables.get(DEFAULT_REGISTRATION_ID_URI_VARIABLE_NAME)) + .cast(String.class) + .flatMap(clientRegistrationId -> resolve(exchange, clientRegistrationId)); + } + + @Override + public Mono resolve(ServerWebExchange exchange, + String clientRegistrationId) { + return this.findByRegistrationId(exchange, clientRegistrationId) + .map(clientRegistration -> authorizationRequest(exchange, clientRegistration)); + } + + private Mono findByRegistrationId(ServerWebExchange exchange, String clientRegistration) { + return this.clientRegistrationRepository.findByRegistrationId(clientRegistration) + .switchIfEmpty(Mono.error(() -> new ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid client registration id"))); + } + + private OAuth2AuthorizationRequest authorizationRequest(ServerWebExchange exchange, + ClientRegistration clientRegistration) { + String redirectUriStr = this + .expandRedirectUri(exchange.getRequest(), clientRegistration); + + Map additionalParameters = new HashMap<>(); + additionalParameters.put(OAuth2ParameterNames.REGISTRATION_ID, + clientRegistration.getRegistrationId()); + + OAuth2AuthorizationRequest.Builder builder; + if (AuthorizationGrantType.AUTHORIZATION_CODE.equals(clientRegistration.getAuthorizationGrantType())) { + builder = OAuth2AuthorizationRequest.authorizationCode(); + } + else if (AuthorizationGrantType.IMPLICIT.equals(clientRegistration.getAuthorizationGrantType())) { + builder = OAuth2AuthorizationRequest.implicit(); + } + else { + throw new IllegalArgumentException( + "Invalid Authorization Grant Type (" + clientRegistration.getAuthorizationGrantType().getValue() + + ") for Client Registration with Id: " + clientRegistration.getRegistrationId()); + } + return builder + .clientId(clientRegistration.getClientId()) + .authorizationUri(clientRegistration.getProviderDetails().getAuthorizationUri()) + .redirectUri(redirectUriStr).scopes(clientRegistration.getScopes()) + .state(this.stateGenerator.generateKey()) + .additionalParameters(additionalParameters) + .build(); + } + + private String expandRedirectUri(ServerHttpRequest request, ClientRegistration clientRegistration) { + // Supported URI variables -> baseUrl, action, registrationId + // Used in -> CommonOAuth2Provider.DEFAULT_REDIRECT_URL = "{baseUrl}/{action}/oauth2/code/{registrationId}" + Map uriVariables = new HashMap<>(); + uriVariables.put("registrationId", clientRegistration.getRegistrationId()); + + String baseUrl = UriComponentsBuilder.fromHttpRequest(new ServerHttpRequestDecorator(request)) + .replacePath(request.getPath().contextPath().value()) + .replaceQuery(null) + .build() + .toUriString(); + uriVariables.put("baseUrl", baseUrl); + + if (AuthorizationGrantType.AUTHORIZATION_CODE.equals(clientRegistration.getAuthorizationGrantType())) { + String loginAction = "login"; + uriVariables.put("action", loginAction); + } + + return UriComponentsBuilder.fromUriString(clientRegistration.getRedirectUriTemplate()) + .buildAndExpand(uriVariables) + .toUriString(); + } +} diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/OAuth2AuthorizationRequestRedirectWebFilter.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/OAuth2AuthorizationRequestRedirectWebFilter.java index 5020ecd968..13e63f86f6 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/OAuth2AuthorizationRequestRedirectWebFilter.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/OAuth2AuthorizationRequestRedirectWebFilter.java @@ -15,16 +15,6 @@ */ package org.springframework.security.oauth2.client.web.server; -import java.net.URI; -import java.util.Base64; -import java.util.HashMap; -import java.util.Map; - -import org.springframework.http.HttpStatus; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.http.server.reactive.ServerHttpRequestDecorator; -import org.springframework.security.crypto.keygen.Base64StringKeyGenerator; -import org.springframework.security.crypto.keygen.StringKeyGenerator; import org.springframework.security.oauth2.client.ClientAuthorizationRequiredException; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; @@ -32,19 +22,17 @@ import org.springframework.security.oauth2.client.registration.ReactiveClientReg import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository; import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; -import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; import org.springframework.security.web.server.DefaultServerRedirectStrategy; import org.springframework.security.web.server.ServerRedirectStrategy; -import org.springframework.security.web.server.util.matcher.PathPatternParserServerWebExchangeMatcher; -import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher; import org.springframework.util.Assert; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilterChain; import org.springframework.web.util.UriComponentsBuilder; - import reactor.core.publisher.Mono; +import java.net.URI; + /** * This {@code WebFilter} initiates the authorization code grant or implicit grant flow * by redirecting the End-User's user-agent to the Authorization Server's Authorization Endpoint. @@ -63,10 +51,6 @@ import reactor.core.publisher.Mono; * {@link ClientRegistration#getRegistrationId() registration identifier} of the client * that is used for initiating the OAuth 2.0 Authorization Request. * - *

- * NOTE: The default base {@code URI} {@code /oauth2/authorization} may be overridden - * via it's constructor {@link #OAuth2AuthorizationRequestRedirectWebFilter(ReactiveClientRegistrationRepository, String)}. - * @author Rob Winch * @since 5.1 * @see OAuth2AuthorizationRequest @@ -79,17 +63,8 @@ import reactor.core.publisher.Mono; * @see Section 4.2.1 Authorization Request (Implicit) */ public class OAuth2AuthorizationRequestRedirectWebFilter implements WebFilter { - /** - * The default base {@code URI} used for authorization requests. - */ - public static final String DEFAULT_AUTHORIZATION_REQUEST_BASE_URI = "/oauth2/authorization"; - private static final String REGISTRATION_ID_URI_VARIABLE_NAME = "registrationId"; - private static final String AUTHORIZATION_REQUIRED_EXCEPTION_ATTR_NAME = - ClientAuthorizationRequiredException.class.getName() + ".AUTHORIZATION_REQUIRED_EXCEPTION"; - private final ServerWebExchangeMatcher authorizationRequestMatcher; - private final ReactiveClientRegistrationRepository clientRegistrationRepository; private final ServerRedirectStrategy authorizationRedirectStrategy = new DefaultServerRedirectStrategy(); - private final StringKeyGenerator stateGenerator = new Base64StringKeyGenerator(Base64.getUrlEncoder()); + private final ServerOAuth2AuthorizationRequestResolver authorizationRequestResolver; private ServerAuthorizationRequestRepository authorizationRequestRepository = new WebSessionOAuth2ServerAuthorizationRequestRepository(); @@ -99,23 +74,17 @@ public class OAuth2AuthorizationRequestRedirectWebFilter implements WebFilter { * @param clientRegistrationRepository the repository of client registrations */ public OAuth2AuthorizationRequestRedirectWebFilter(ReactiveClientRegistrationRepository clientRegistrationRepository) { - this(clientRegistrationRepository, DEFAULT_AUTHORIZATION_REQUEST_BASE_URI); + this.authorizationRequestResolver = new DefaultServerOAuth2AuthorizationRequestResolver(clientRegistrationRepository); } /** * Constructs an {@code OAuth2AuthorizationRequestRedirectFilter} using the provided parameters. * - * @param clientRegistrationRepository the repository of client registrations - * @param authorizationRequestBaseUri the base {@code URI} used for authorization requests + * @param authorizationRequestResolver the resolver to use */ - public OAuth2AuthorizationRequestRedirectWebFilter( - ReactiveClientRegistrationRepository clientRegistrationRepository, String authorizationRequestBaseUri) { - - Assert.hasText(authorizationRequestBaseUri, "authorizationRequestBaseUri cannot be empty"); - Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null"); - this.authorizationRequestMatcher = new PathPatternParserServerWebExchangeMatcher( - authorizationRequestBaseUri + "/{" + REGISTRATION_ID_URI_VARIABLE_NAME + "}"); - this.clientRegistrationRepository = clientRegistrationRepository; + public OAuth2AuthorizationRequestRedirectWebFilter(ServerOAuth2AuthorizationRequestResolver authorizationRequestResolver) { + Assert.notNull(authorizationRequestResolver, "authorizationRequestResolver cannot be null"); + this.authorizationRequestResolver = authorizationRequestResolver; } /** @@ -131,54 +100,15 @@ public class OAuth2AuthorizationRequestRedirectWebFilter implements WebFilter { @Override public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { - return this.authorizationRequestMatcher.matches(exchange) - .filter(matchResult -> matchResult.isMatch()) + return this.authorizationRequestResolver.resolve(exchange) .switchIfEmpty(chain.filter(exchange).then(Mono.empty())) - .map(ServerWebExchangeMatcher.MatchResult::getVariables) - .map(variables -> variables.get(REGISTRATION_ID_URI_VARIABLE_NAME)) - .cast(String.class) - .onErrorResume(ClientAuthorizationRequiredException.class, e -> Mono.just(e.getClientRegistrationId())) - .flatMap(clientRegistrationId -> this.findByRegistrationId(exchange, clientRegistrationId)) + .onErrorResume(ClientAuthorizationRequiredException.class, e -> this.authorizationRequestResolver.resolve(exchange, e.getClientRegistrationId())) .flatMap(clientRegistration -> sendRedirectForAuthorization(exchange, clientRegistration)); } - private Mono findByRegistrationId(ServerWebExchange exchange, String clientRegistration) { - return this.clientRegistrationRepository.findByRegistrationId(clientRegistration) - .switchIfEmpty(Mono.defer(() -> { - exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST); - return exchange.getResponse().setComplete().then(Mono.empty()); - })); - } - private Mono sendRedirectForAuthorization(ServerWebExchange exchange, - ClientRegistration clientRegistration) { + OAuth2AuthorizationRequest authorizationRequest) { return Mono.defer(() -> { - String redirectUriStr = this - .expandRedirectUri(exchange.getRequest(), clientRegistration); - - Map additionalParameters = new HashMap<>(); - additionalParameters.put(OAuth2ParameterNames.REGISTRATION_ID, - clientRegistration.getRegistrationId()); - - OAuth2AuthorizationRequest.Builder builder; - if (AuthorizationGrantType.AUTHORIZATION_CODE.equals(clientRegistration.getAuthorizationGrantType())) { - builder = OAuth2AuthorizationRequest.authorizationCode(); - } - else if (AuthorizationGrantType.IMPLICIT.equals(clientRegistration.getAuthorizationGrantType())) { - builder = OAuth2AuthorizationRequest.implicit(); - } - else { - throw new IllegalArgumentException( - "Invalid Authorization Grant Type (" + clientRegistration.getAuthorizationGrantType().getValue() - + ") for Client Registration with Id: " + clientRegistration.getRegistrationId()); - } - OAuth2AuthorizationRequest authorizationRequest = builder - .clientId(clientRegistration.getClientId()) - .authorizationUri(clientRegistration.getProviderDetails().getAuthorizationUri()) - .redirectUri(redirectUriStr).scopes(clientRegistration.getScopes()) - .state(this.stateGenerator.generateKey()) - .additionalParameters(additionalParameters).build(); - Mono saveAuthorizationRequest = Mono.empty(); if (AuthorizationGrantType.AUTHORIZATION_CODE.equals(authorizationRequest.getGrantType())) { saveAuthorizationRequest = this.authorizationRequestRepository @@ -192,27 +122,4 @@ public class OAuth2AuthorizationRequestRedirectWebFilter implements WebFilter { .then(this.authorizationRedirectStrategy.sendRedirect(exchange, redirectUri)); }); } - - private String expandRedirectUri(ServerHttpRequest request, ClientRegistration clientRegistration) { - // Supported URI variables -> baseUrl, action, registrationId - // Used in -> CommonOAuth2Provider.DEFAULT_REDIRECT_URL = "{baseUrl}/{action}/oauth2/code/{registrationId}" - Map uriVariables = new HashMap<>(); - uriVariables.put("registrationId", clientRegistration.getRegistrationId()); - - String baseUrl = UriComponentsBuilder.fromHttpRequest(new ServerHttpRequestDecorator(request)) - .replacePath(request.getPath().contextPath().value()) - .replaceQuery(null) - .build() - .toUriString(); - uriVariables.put("baseUrl", baseUrl); - - if (AuthorizationGrantType.AUTHORIZATION_CODE.equals(clientRegistration.getAuthorizationGrantType())) { - String loginAction = "login"; - uriVariables.put("action", loginAction); - } - - return UriComponentsBuilder.fromUriString(clientRegistration.getRedirectUriTemplate()) - .buildAndExpand(uriVariables) - .toUriString(); - } } diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/ServerOAuth2AuthorizationRequestResolver.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/ServerOAuth2AuthorizationRequestResolver.java new file mode 100644 index 0000000000..598191fd92 --- /dev/null +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/ServerOAuth2AuthorizationRequestResolver.java @@ -0,0 +1,53 @@ +/* + * Copyright 2002-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.security.oauth2.client.web.server; + +import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +/** + * Implementations of this interface are capable of resolving + * an {@link OAuth2AuthorizationRequest} from the provided {@code ServerWebExchange}. + * Used by the {@link OAuth2AuthorizationRequestRedirectWebFilter} for resolving Authorization Requests. + * + * @author Rob Winch + * @since 5.1 + * @see OAuth2AuthorizationRequest + * @see OAuth2AuthorizationRequestRedirectWebFilter + */ +public interface ServerOAuth2AuthorizationRequestResolver { + + /** + * Returns the {@link OAuth2AuthorizationRequest} resolved from + * the provided {@code HttpServletRequest} or {@code null} if not available. + * + * @param exchange the {@code ServerWebExchange} + * @return the resolved {@link OAuth2AuthorizationRequest} or {@code null} if not available + */ + Mono resolve(ServerWebExchange exchange); + + /** + * Returns the {@link OAuth2AuthorizationRequest} resolved from + * the provided {@code HttpServletRequest} or {@code null} if not available. + * + * @param exchange the {@code ServerWebExchange} + * @param clientRegistrationId the client registration id + * @return the resolved {@link OAuth2AuthorizationRequest} or {@code null} if not available + */ + Mono resolve(ServerWebExchange exchange, String clientRegistrationId); + +} diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/DefaultServerOAuth2AuthorizationRequestResolverTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/DefaultServerOAuth2AuthorizationRequestResolverTests.java new file mode 100644 index 0000000000..cd980ef812 --- /dev/null +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/DefaultServerOAuth2AuthorizationRequestResolverTests.java @@ -0,0 +1,87 @@ +/* + * Copyright 2002-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.security.oauth2.client.web.server; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.http.HttpStatus; +import org.springframework.mock.http.server.reactive.MockServerHttpRequest; +import org.springframework.mock.web.server.MockServerWebExchange; +import org.springframework.security.oauth2.client.registration.ClientRegistration; +import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository; +import org.springframework.security.oauth2.client.registration.TestClientRegistrations; +import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; +import org.springframework.web.server.ResponseStatusException; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.catchThrowableOfType; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +/** + * @author Rob Winch + * @since 5.1 + */ +@RunWith(MockitoJUnitRunner.class) +public class DefaultServerOAuth2AuthorizationRequestResolverTests { + @Mock + private ReactiveClientRegistrationRepository clientRegistrationRepository; + + private DefaultServerOAuth2AuthorizationRequestResolver resolver; + + private ClientRegistration registration = TestClientRegistrations.clientRegistration().build(); + + @Before + public void setup() { + this.resolver = new DefaultServerOAuth2AuthorizationRequestResolver(this.clientRegistrationRepository); + } + + @Test + public void resolveWhenNotMatchThenNull() { + assertThat(resolve("/")).isNull(); + } + + @Test + public void resolveWhenClientRegistrationNotFoundMatchThenBadRequest() { + when(this.clientRegistrationRepository.findByRegistrationId(any())).thenReturn( + Mono.empty()); + + ResponseStatusException expected = catchThrowableOfType(() -> resolve("/oauth2/authorization/not-found-id"), ResponseStatusException.class); + + assertThat(expected.getStatus()).isEqualTo(HttpStatus.BAD_REQUEST); + } + + @Test + public void resolveWhenClientRegistrationFoundThenWorks() { + when(this.clientRegistrationRepository.findByRegistrationId(any())).thenReturn( + Mono.just(this.registration)); + + OAuth2AuthorizationRequest request = resolve("/oauth2/authorization/not-found-id"); + + assertThat(request.getAuthorizationRequestUri()).matches("https://example.com/login/oauth/authorize\\?response_type=code&client_id=client-id&scope=read%3Auser&state=.*?&redirect_uri=%2Flogin%2Foauth2%2Fcode%2Fregistration-id"); + } + + private OAuth2AuthorizationRequest resolve(String path) { + ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get(path)); + return this.resolver.resolve(exchange).block(); + } +} diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/OAuth2AuthorizationRequestRedirectWebFilterTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/OAuth2AuthorizationRequestRedirectWebFilterTests.java index 7dd49f2ae5..fdface6d72 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/OAuth2AuthorizationRequestRedirectWebFilterTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/web/server/OAuth2AuthorizationRequestRedirectWebFilterTests.java @@ -79,20 +79,6 @@ public class OAuth2AuthorizationRequestRedirectWebFilterTests { .isInstanceOf(IllegalArgumentException.class); } - @Test - public void constructorWhenAuthorizationRequestBaseUriNullThenIllegalArgumentException() { - String authorizationRequestBaseUri = null; - assertThatThrownBy(() -> new OAuth2AuthorizationRequestRedirectWebFilter(this.clientRepository, authorizationRequestBaseUri)) - .isInstanceOf(IllegalArgumentException.class); - } - - @Test - public void constructorWhenAuthorizationRequestBaseUriEmptyThenIllegalArgumentException() { - String authorizationRequestBaseUri = ""; - assertThatThrownBy(() -> new OAuth2AuthorizationRequestRedirectWebFilter(this.clientRepository, authorizationRequestBaseUri)) - .isInstanceOf(IllegalArgumentException.class); - } - @Test public void filterWhenDoesNotMatchThenClientRegistrationRepositoryNotSubscribed() { this.client.get()