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 903bf7ea88..f843b5379c 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 @@ -85,13 +85,13 @@ public class OidcClientInitiatedServerLogoutSuccessHandler implements ServerLogo return Mono.empty(); } String idToken = idToken(authentication); - URI postLogoutRedirectUri = postLogoutRedirectUri(exchange.getExchange().getRequest()); + String postLogoutRedirectUri = postLogoutRedirectUri(exchange.getExchange().getRequest()); return Mono.just(endpointUri(endSessionEndpoint, idToken, postLogoutRedirectUri)); }) .switchIfEmpty( this.serverLogoutSuccessHandler.onLogoutSuccess(exchange, authentication).then(Mono.empty()) ) - .flatMap((endpointUri) -> this.redirectStrategy.sendRedirect(exchange.getExchange(), endpointUri)); + .flatMap((endpointUri) -> this.redirectStrategy.sendRedirect(exchange.getExchange(), URI.create(endpointUri))); // @formatter:on } @@ -106,20 +106,20 @@ public class OidcClientInitiatedServerLogoutSuccessHandler implements ServerLogo return null; } - private URI endpointUri(URI endSessionEndpoint, String idToken, URI postLogoutRedirectUri) { + private String endpointUri(URI endSessionEndpoint, String idToken, String postLogoutRedirectUri) { UriComponentsBuilder builder = UriComponentsBuilder.fromUri(endSessionEndpoint); builder.queryParam("id_token_hint", idToken); if (postLogoutRedirectUri != null) { builder.queryParam("post_logout_redirect_uri", postLogoutRedirectUri); } - return builder.encode(StandardCharsets.UTF_8).build().toUri(); + return builder.encode(StandardCharsets.UTF_8).build().toUriString(); } private String idToken(Authentication authentication) { return ((OidcUser) authentication.getPrincipal()).getIdToken().getTokenValue(); } - private URI postLogoutRedirectUri(ServerHttpRequest request) { + private String postLogoutRedirectUri(ServerHttpRequest request) { if (this.postLogoutRedirectUri == null) { return null; } @@ -131,7 +131,7 @@ public class OidcClientInitiatedServerLogoutSuccessHandler implements ServerLogo .build(); return UriComponentsBuilder.fromUriString(this.postLogoutRedirectUri) .buildAndExpand(Collections.singletonMap("baseUrl", uriComponents.toUriString())) - .toUri(); + .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 2a28fea70a..acde8f91e5 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 @@ -150,6 +150,19 @@ public class OidcClientInitiatedServerLogoutSuccessHandlerTests { "https://endpoint?" + "id_token_hint=id-token&" + "post_logout_redirect_uri=https://rp.example.org"); } + // gh-11379 + @Test + public void logoutWhenUsingPostLogoutRedirectUriWithQueryParametersThenBuildsItForRedirect() { + OAuth2AuthenticationToken token = new OAuth2AuthenticationToken(TestOidcUsers.create(), + AuthorityUtils.NO_AUTHORITIES, this.registration.getRegistrationId()); + given(this.exchange.getPrincipal()).willReturn(Mono.just(token)); + this.handler.setPostLogoutRedirectUri("https://rp.example.org/context?forwardUrl=secured%3Fparam%3Dtrue"); + WebFilterExchange f = new WebFilterExchange(this.exchange, this.chain); + this.handler.onLogoutSuccess(f, token).block(); + assertThat(redirectedUrl(this.exchange)).isEqualTo("https://endpoint?id_token_hint=id-token&" + + "post_logout_redirect_uri=https://rp.example.org/context?forwardUrl%3Dsecured%253Fparam%253Dtrue"); + } + @Test public void setPostLogoutRedirectUriWhenGivenNullThenThrowsException() { assertThatIllegalArgumentException().isThrownBy(() -> this.handler.setPostLogoutRedirectUri((URI) null));