OAuth 2.0 logout handler resolves uri placeholders

- OidcClientInitiatedLogoutSuccessHandler can automatically resolve placeholders like baseUrl and registrationId inside the postLogoutRedirectUri

Issue gh-7900
This commit is contained in:
Simone Giannino 2022-03-05 15:01:31 +01:00 committed by Josh Cummings
parent fabeabd2db
commit 73003d59d6
2 changed files with 28 additions and 6 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2020 the original author or authors. * Copyright 2002-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,7 +18,8 @@ package org.springframework.security.oauth2.client.oidc.web.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 javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -67,7 +68,7 @@ public final class OidcClientInitiatedLogoutSuccessHandler extends SimpleUrlLogo
URI endSessionEndpoint = this.endSessionEndpoint(clientRegistration); URI endSessionEndpoint = this.endSessionEndpoint(clientRegistration);
if (endSessionEndpoint != null) { if (endSessionEndpoint != null) {
String idToken = idToken(authentication); String idToken = idToken(authentication);
String postLogoutRedirectUri = postLogoutRedirectUri(request); String postLogoutRedirectUri = postLogoutRedirectUri(request, clientRegistration);
targetUrl = endpointUri(endSessionEndpoint, idToken, postLogoutRedirectUri); targetUrl = endpointUri(endSessionEndpoint, idToken, postLogoutRedirectUri);
} }
} }
@ -89,7 +90,7 @@ public final class OidcClientInitiatedLogoutSuccessHandler extends SimpleUrlLogo
return ((OidcUser) authentication.getPrincipal()).getIdToken().getTokenValue(); return ((OidcUser) authentication.getPrincipal()).getIdToken().getTokenValue();
} }
private String postLogoutRedirectUri(HttpServletRequest request) { private String postLogoutRedirectUri(HttpServletRequest request, ClientRegistration clientRegistration) {
if (this.postLogoutRedirectUri == null) { if (this.postLogoutRedirectUri == null) {
return null; return null;
} }
@ -100,8 +101,13 @@ public final class OidcClientInitiatedLogoutSuccessHandler extends SimpleUrlLogo
.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

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2020 the original author or authors. * Copyright 2002-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -138,6 +138,22 @@ public class OidcClientInitiatedLogoutSuccessHandlerTests {
"https://endpoint?" + "id_token_hint=id-token&" + "post_logout_redirect_uri=https://rp.example.org"); "https://endpoint?" + "id_token_hint=id-token&" + "post_logout_redirect_uri=https://rp.example.org");
} }
@Test
public void logoutWhenUsingPostLogoutRedirectUriTemplateThenBuildsItForRedirectExpanded()
throws IOException, ServletException {
OAuth2AuthenticationToken token = new OAuth2AuthenticationToken(TestOidcUsers.create(),
AuthorityUtils.NO_AUTHORITIES, this.registration.getRegistrationId());
this.handler.setPostLogoutRedirectUri("{baseUrl}/{registrationId}");
this.request.setScheme("https");
this.request.setServerPort(443);
this.request.setServerName("rp.example.org");
this.request.setUserPrincipal(token);
this.handler.onLogoutSuccess(this.request, this.response, token);
assertThat(this.response.getRedirectedUrl()).isEqualTo(String.format(
"https://endpoint?" + "id_token_hint=id-token&" + "post_logout_redirect_uri=https://rp.example.org/%s",
this.registration.getRegistrationId()));
}
// gh-9511 // gh-9511
@Test @Test
public void logoutWhenUsingPostLogoutRedirectUriWithQueryParametersThenBuildsItForRedirect() public void logoutWhenUsingPostLogoutRedirectUriWithQueryParametersThenBuildsItForRedirect()