Skip to content

Commit 385bdfc

Browse files
committed
OAuth2AuthorizationCodeGrantWebFilter works with /{action}/
This ensures that the same URL can work for both log in and authorization code which prevents having to create additional registrations on the client and potentially on the server (GitHub only allows a single valid redirect URL). Fixes: gh-5856
1 parent 26afc18 commit 385bdfc

File tree

3 files changed

+12
-3
lines changed

3 files changed

+12
-3
lines changed

config/src/main/java/org/springframework/security/config/web/server/SecurityWebFiltersOrder.java

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public enum SecurityWebFiltersOrder {
4848
*/
4949
FORM_LOGIN,
5050
AUTHENTICATION,
51+
OAUTH2_AUTHORIZATION_CODE,
5152
LOGIN_PAGE_GENERATING,
5253
LOGOUT_PAGE_GENERATING,
5354
/**

config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java

+10-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.List;
2929
import java.util.Map;
3030

31+
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
3132
import reactor.core.publisher.Mono;
3233
import reactor.util.context.Context;
3334

@@ -552,7 +553,7 @@ protected void configure(ServerHttpSecurity http) {
552553
}
553554

554555
AuthenticationWebFilter authenticationFilter = new OAuth2LoginAuthenticationWebFilter(manager, authorizedClientRepository);
555-
authenticationFilter.setRequiresAuthenticationMatcher(new PathPatternParserServerWebExchangeMatcher("/login/oauth2/code/{registrationId}"));
556+
authenticationFilter.setRequiresAuthenticationMatcher(createAttemptAuthenticationRequestMatcher());
556557
authenticationFilter.setServerAuthenticationConverter(new ServerOAuth2AuthorizationCodeAuthenticationTokenConverter(clientRegistrationRepository));
557558

558559
RedirectServerAuthenticationSuccessHandler redirectHandler = new RedirectServerAuthenticationSuccessHandler();
@@ -581,6 +582,13 @@ public Mono<Void> onAuthenticationFailure(WebFilterExchange webFilterExchange,
581582
http.addFilterAt(authenticationFilter, SecurityWebFiltersOrder.AUTHENTICATION);
582583
}
583584

585+
private ServerWebExchangeMatcher createAttemptAuthenticationRequestMatcher() {
586+
PathPatternParserServerWebExchangeMatcher loginPathMatcher = new PathPatternParserServerWebExchangeMatcher("/login/oauth2/code/{registrationId}");
587+
ServerWebExchangeMatcher notAuthenticatedMatcher = e -> ReactiveSecurityContextHolder.getContext()
588+
.flatMap(p -> ServerWebExchangeMatcher.MatchResult.notMatch())
589+
.switchIfEmpty(ServerWebExchangeMatcher.MatchResult.match());
590+
return new AndServerWebExchangeMatcher(loginPathMatcher, notAuthenticatedMatcher);
591+
}
584592
private Map<String, String> getLinks() {
585593
Iterable<ClientRegistration> registrations = getBeanOrNull(ResolvableType.forClassWithGenerics(Iterable.class, ClientRegistration.class));
586594
if (registrations == null) {
@@ -686,7 +694,7 @@ protected void configure(ServerHttpSecurity http) {
686694

687695
OAuth2AuthorizationRequestRedirectWebFilter oauthRedirectFilter = new OAuth2AuthorizationRequestRedirectWebFilter(
688696
clientRegistrationRepository);
689-
http.addFilterAt(codeGrantWebFilter, SecurityWebFiltersOrder.AUTHENTICATION);
697+
http.addFilterAt(codeGrantWebFilter, SecurityWebFiltersOrder.OAUTH2_AUTHORIZATION_CODE);
690698
http.addFilterAt(oauthRedirectFilter, SecurityWebFiltersOrder.HTTP_BASIC);
691699
}
692700

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/OAuth2AuthorizationCodeGrantWebFilter.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public OAuth2AuthorizationCodeGrantWebFilter(
109109
Assert.notNull(authorizedClientRepository, "authorizedClientRepository cannot be null");
110110
this.authenticationManager = authenticationManager;
111111
this.authorizedClientRepository = authorizedClientRepository;
112-
this.requiresAuthenticationMatcher = new PathPatternParserServerWebExchangeMatcher("/authorize/oauth2/code/{registrationId}");
112+
this.requiresAuthenticationMatcher = new PathPatternParserServerWebExchangeMatcher("/{action}/oauth2/code/{registrationId}");
113113
this.authenticationConverter = new ServerOAuth2AuthorizationCodeAuthenticationTokenConverter(clientRegistrationRepository);
114114
this.authenticationSuccessHandler = new RedirectServerAuthenticationSuccessHandler();
115115
this.authenticationFailureHandler = (webFilterExchange, exception) -> Mono.error(exception);

0 commit comments

Comments
 (0)