From 385bdfc055854581e9e9f671d11f86a978c27c42 Mon Sep 17 00:00:00 2001 From: Rob Winch Date: Fri, 14 Sep 2018 11:11:51 -0500 Subject: [PATCH] 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 --- .../config/web/server/SecurityWebFiltersOrder.java | 1 + .../config/web/server/ServerHttpSecurity.java | 12 ++++++++++-- .../OAuth2AuthorizationCodeGrantWebFilter.java | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/config/src/main/java/org/springframework/security/config/web/server/SecurityWebFiltersOrder.java b/config/src/main/java/org/springframework/security/config/web/server/SecurityWebFiltersOrder.java index a272ae7363..6e1f1db678 100644 --- a/config/src/main/java/org/springframework/security/config/web/server/SecurityWebFiltersOrder.java +++ b/config/src/main/java/org/springframework/security/config/web/server/SecurityWebFiltersOrder.java @@ -48,6 +48,7 @@ public enum SecurityWebFiltersOrder { */ FORM_LOGIN, AUTHENTICATION, + OAUTH2_AUTHORIZATION_CODE, LOGIN_PAGE_GENERATING, LOGOUT_PAGE_GENERATING, /** diff --git a/config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java b/config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java index 8f2b790ddd..009f8c61f5 100644 --- a/config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java +++ b/config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java @@ -28,6 +28,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.springframework.security.core.context.ReactiveSecurityContextHolder; import reactor.core.publisher.Mono; import reactor.util.context.Context; @@ -552,7 +553,7 @@ public class ServerHttpSecurity { } AuthenticationWebFilter authenticationFilter = new OAuth2LoginAuthenticationWebFilter(manager, authorizedClientRepository); - authenticationFilter.setRequiresAuthenticationMatcher(new PathPatternParserServerWebExchangeMatcher("/login/oauth2/code/{registrationId}")); + authenticationFilter.setRequiresAuthenticationMatcher(createAttemptAuthenticationRequestMatcher()); authenticationFilter.setServerAuthenticationConverter(new ServerOAuth2AuthorizationCodeAuthenticationTokenConverter(clientRegistrationRepository)); RedirectServerAuthenticationSuccessHandler redirectHandler = new RedirectServerAuthenticationSuccessHandler(); @@ -581,6 +582,13 @@ public class ServerHttpSecurity { http.addFilterAt(authenticationFilter, SecurityWebFiltersOrder.AUTHENTICATION); } + private ServerWebExchangeMatcher createAttemptAuthenticationRequestMatcher() { + PathPatternParserServerWebExchangeMatcher loginPathMatcher = new PathPatternParserServerWebExchangeMatcher("/login/oauth2/code/{registrationId}"); + ServerWebExchangeMatcher notAuthenticatedMatcher = e -> ReactiveSecurityContextHolder.getContext() + .flatMap(p -> ServerWebExchangeMatcher.MatchResult.notMatch()) + .switchIfEmpty(ServerWebExchangeMatcher.MatchResult.match()); + return new AndServerWebExchangeMatcher(loginPathMatcher, notAuthenticatedMatcher); + } private Map getLinks() { Iterable registrations = getBeanOrNull(ResolvableType.forClassWithGenerics(Iterable.class, ClientRegistration.class)); if (registrations == null) { @@ -686,7 +694,7 @@ public class ServerHttpSecurity { OAuth2AuthorizationRequestRedirectWebFilter oauthRedirectFilter = new OAuth2AuthorizationRequestRedirectWebFilter( clientRegistrationRepository); - http.addFilterAt(codeGrantWebFilter, SecurityWebFiltersOrder.AUTHENTICATION); + http.addFilterAt(codeGrantWebFilter, SecurityWebFiltersOrder.OAUTH2_AUTHORIZATION_CODE); http.addFilterAt(oauthRedirectFilter, SecurityWebFiltersOrder.HTTP_BASIC); } diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/OAuth2AuthorizationCodeGrantWebFilter.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/OAuth2AuthorizationCodeGrantWebFilter.java index 25ab879773..d3ffdd0ed6 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/OAuth2AuthorizationCodeGrantWebFilter.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/server/OAuth2AuthorizationCodeGrantWebFilter.java @@ -109,7 +109,7 @@ public class OAuth2AuthorizationCodeGrantWebFilter implements WebFilter { Assert.notNull(authorizedClientRepository, "authorizedClientRepository cannot be null"); this.authenticationManager = authenticationManager; this.authorizedClientRepository = authorizedClientRepository; - this.requiresAuthenticationMatcher = new PathPatternParserServerWebExchangeMatcher("/authorize/oauth2/code/{registrationId}"); + this.requiresAuthenticationMatcher = new PathPatternParserServerWebExchangeMatcher("/{action}/oauth2/code/{registrationId}"); this.authenticationConverter = new ServerOAuth2AuthorizationCodeAuthenticationTokenConverter(clientRegistrationRepository); this.authenticationSuccessHandler = new RedirectServerAuthenticationSuccessHandler(); this.authenticationFailureHandler = (webFilterExchange, exception) -> Mono.error(exception);