From ebb5746f6e17a6793c58cc0939ff6cb3f3741197 Mon Sep 17 00:00:00 2001 From: Josh Cummings Date: Thu, 16 Jun 2022 14:50:39 -0600 Subject: [PATCH] Reactive OAuth 2.0 logout handler resolves registrationId Closes gh-11378 --- ...lientInitiatedServerLogoutSuccessHandler.java | 14 ++++++++++---- ...InitiatedServerLogoutSuccessHandlerTests.java | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/web/server/logout/OidcClientInitiatedServerLogoutSuccessHandler.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/web/server/logout/OidcClientInitiatedServerLogoutSuccessHandler.java index f843b5379c..080c70fa64 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/web/server/logout/OidcClientInitiatedServerLogoutSuccessHandler.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/web/server/logout/OidcClientInitiatedServerLogoutSuccessHandler.java @@ -18,7 +18,8 @@ package org.springframework.security.oauth2.client.oidc.web.server.logout; import java.net.URI; import java.nio.charset.StandardCharsets; -import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import reactor.core.publisher.Mono; @@ -85,7 +86,7 @@ public class OidcClientInitiatedServerLogoutSuccessHandler implements ServerLogo return Mono.empty(); } String idToken = idToken(authentication); - String postLogoutRedirectUri = postLogoutRedirectUri(exchange.getExchange().getRequest()); + String postLogoutRedirectUri = postLogoutRedirectUri(exchange.getExchange().getRequest(), clientRegistration); return Mono.just(endpointUri(endSessionEndpoint, idToken, postLogoutRedirectUri)); }) .switchIfEmpty( @@ -119,7 +120,7 @@ public class OidcClientInitiatedServerLogoutSuccessHandler implements ServerLogo return ((OidcUser) authentication.getPrincipal()).getIdToken().getTokenValue(); } - private String postLogoutRedirectUri(ServerHttpRequest request) { + private String postLogoutRedirectUri(ServerHttpRequest request, ClientRegistration clientRegistration) { if (this.postLogoutRedirectUri == null) { return null; } @@ -129,8 +130,13 @@ public class OidcClientInitiatedServerLogoutSuccessHandler implements ServerLogo .replaceQuery(null) .fragment(null) .build(); + + Map uriVariables = new HashMap<>(); + uriVariables.put("baseUrl", uriComponents.toUriString()); + uriVariables.put("registrationId", clientRegistration.getRegistrationId()); + return UriComponentsBuilder.fromUriString(this.postLogoutRedirectUri) - .buildAndExpand(Collections.singletonMap("baseUrl", uriComponents.toUriString())) + .buildAndExpand(uriVariables) .toUriString(); // @formatter:on } diff --git a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/web/server/logout/OidcClientInitiatedServerLogoutSuccessHandlerTests.java b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/web/server/logout/OidcClientInitiatedServerLogoutSuccessHandlerTests.java index 5191e8e747..755f176080 100644 --- a/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/web/server/logout/OidcClientInitiatedServerLogoutSuccessHandlerTests.java +++ b/oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/web/server/logout/OidcClientInitiatedServerLogoutSuccessHandlerTests.java @@ -162,6 +162,22 @@ public class OidcClientInitiatedServerLogoutSuccessHandlerTests { + "post_logout_redirect_uri=https://rp.example.org/context?forwardUrl%3Dsecured%253Fparam%253Dtrue"); } + @Test + public void logoutWhenUsingPostLogoutRedirectUriTemplateThenBuildsItForRedirectExpanded() + throws IOException, ServletException { + OAuth2AuthenticationToken token = new OAuth2AuthenticationToken(TestOidcUsers.create(), + AuthorityUtils.NO_AUTHORITIES, this.registration.getRegistrationId()); + given(this.exchange.getPrincipal()).willReturn(Mono.just(token)); + MockServerHttpRequest request = MockServerHttpRequest.get("https://rp.example.org/").build(); + given(this.exchange.getRequest()).willReturn(request); + WebFilterExchange f = new WebFilterExchange(this.exchange, this.chain); + this.handler.setPostLogoutRedirectUri("{baseUrl}/{registrationId}"); + this.handler.onLogoutSuccess(f, token).block(); + assertThat(redirectedUrl(this.exchange)).isEqualTo(String.format( + "https://endpoint?" + "id_token_hint=id-token&" + "post_logout_redirect_uri=https://rp.example.org/%s", + this.registration.getRegistrationId())); + } + @Test public void setPostLogoutRedirectUriWhenGivenNullThenThrowsException() { assertThatIllegalArgumentException().isThrownBy(() -> this.handler.setPostLogoutRedirectUri((URI) null));