Reactive OAuth 2.0 logout handler resolves registrationId

Closes gh-11378
This commit is contained in:
Josh Cummings 2022-06-16 14:50:39 -06:00
parent 3f30de388a
commit 6f69d85fcb
No known key found for this signature in database
GPG Key ID: A306A51F43B8E5A5
2 changed files with 26 additions and 4 deletions

View File

@ -18,7 +18,8 @@ package org.springframework.security.oauth2.client.oidc.web.server.logout;
import java.net.URI; import java.net.URI;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Collections; import java.util.HashMap;
import java.util.Map;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@ -85,7 +86,7 @@ public class OidcClientInitiatedServerLogoutSuccessHandler implements ServerLogo
return Mono.empty(); return Mono.empty();
} }
String idToken = idToken(authentication); String idToken = idToken(authentication);
String postLogoutRedirectUri = postLogoutRedirectUri(exchange.getExchange().getRequest()); String postLogoutRedirectUri = postLogoutRedirectUri(exchange.getExchange().getRequest(), clientRegistration);
return Mono.just(endpointUri(endSessionEndpoint, idToken, postLogoutRedirectUri)); return Mono.just(endpointUri(endSessionEndpoint, idToken, postLogoutRedirectUri));
}) })
.switchIfEmpty( .switchIfEmpty(
@ -119,7 +120,7 @@ public class OidcClientInitiatedServerLogoutSuccessHandler implements ServerLogo
return ((OidcUser) authentication.getPrincipal()).getIdToken().getTokenValue(); return ((OidcUser) authentication.getPrincipal()).getIdToken().getTokenValue();
} }
private String postLogoutRedirectUri(ServerHttpRequest request) { private String postLogoutRedirectUri(ServerHttpRequest request, ClientRegistration clientRegistration) {
if (this.postLogoutRedirectUri == null) { if (this.postLogoutRedirectUri == null) {
return null; return null;
} }
@ -129,8 +130,13 @@ public class OidcClientInitiatedServerLogoutSuccessHandler implements ServerLogo
.replaceQuery(null) .replaceQuery(null)
.fragment(null) .fragment(null)
.build(); .build();
Map<String, String> uriVariables = new HashMap<>();
uriVariables.put("baseUrl", uriComponents.toUriString());
uriVariables.put("registrationId", clientRegistration.getRegistrationId());
return UriComponentsBuilder.fromUriString(this.postLogoutRedirectUri) return UriComponentsBuilder.fromUriString(this.postLogoutRedirectUri)
.buildAndExpand(Collections.singletonMap("baseUrl", uriComponents.toUriString())) .buildAndExpand(uriVariables)
.toUriString(); .toUriString();
// @formatter:on // @formatter:on
} }

View File

@ -163,6 +163,22 @@ public class OidcClientInitiatedServerLogoutSuccessHandlerTests {
+ "post_logout_redirect_uri=https://rp.example.org/context?forwardUrl%3Dsecured%253Fparam%253Dtrue"); + "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 @Test
public void setPostLogoutRedirectUriWhenGivenNullThenThrowsException() { public void setPostLogoutRedirectUriWhenGivenNullThenThrowsException() {
assertThatIllegalArgumentException().isThrownBy(() -> this.handler.setPostLogoutRedirectUri((URI) null)); assertThatIllegalArgumentException().isThrownBy(() -> this.handler.setPostLogoutRedirectUri((URI) null));