Browse Source

Add placeholders to post_logout_redirect_uri

Now supports baseScheme, baseHost, basePort, and basePath in addition
to extant baseUrl.

Closes gh-11229
Michael 3 years ago
parent
commit
cb0ab49adc

+ 21 - 2
oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/oidc/web/logout/OidcClientInitiatedLogoutSuccessHandler.java

@@ -103,7 +103,19 @@ public final class OidcClientInitiatedLogoutSuccessHandler extends SimpleUrlLogo
 				.build();
 				.build();
 
 
 		Map<String, String> uriVariables = new HashMap<>();
 		Map<String, String> uriVariables = new HashMap<>();
+		String scheme = uriComponents.getScheme();
+		uriVariables.put("baseScheme", (scheme != null) ? scheme : "");
 		uriVariables.put("baseUrl", uriComponents.toUriString());
 		uriVariables.put("baseUrl", uriComponents.toUriString());
+
+		String host = uriComponents.getHost();
+		uriVariables.put("baseHost", (host != null) ? host : "");
+
+		String path = uriComponents.getPath();
+		uriVariables.put("basePath", (path != null) ? path : "");
+
+		int port = uriComponents.getPort();
+		uriVariables.put("basePort", (port == -1) ? "" : ":" + port);
+
 		uriVariables.put("registrationId", clientRegistration.getRegistrationId());
 		uriVariables.put("registrationId", clientRegistration.getRegistrationId());
 
 
 		return UriComponentsBuilder.fromUriString(this.postLogoutRedirectUri)
 		return UriComponentsBuilder.fromUriString(this.postLogoutRedirectUri)
@@ -138,8 +150,15 @@ public final class OidcClientInitiatedLogoutSuccessHandler extends SimpleUrlLogo
 	}
 	}
 
 
 	/**
 	/**
-	 * Set the post logout redirect uri template to use. Supports the {@code "{baseUrl}"}
-	 * placeholder, for example:
+	 * Set the post logout redirect uri template.
+	 *
+	 * <br />
+	 * The supported uri template variables are: {@code {baseScheme}}, {@code {baseHost}},
+	 * {@code {basePort}} and {@code {basePath}}.
+	 *
+	 * <br />
+	 * <b>NOTE:</b> {@code "{baseUrl}"} is also supported, which is the same as
+	 * {@code "{baseScheme}://{baseHost}{basePort}{basePath}"}
 	 *
 	 *
 	 * <pre>
 	 * <pre>
 	 * 	handler.setPostLogoutRedirectUri("{baseUrl}");
 	 * 	handler.setPostLogoutRedirectUri("{baseUrl}");

+ 31 - 1
oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/oidc/web/logout/OidcClientInitiatedLogoutSuccessHandlerTests.java

@@ -123,7 +123,7 @@ public class OidcClientInitiatedLogoutSuccessHandlerTests {
 	}
 	}
 
 
 	@Test
 	@Test
-	public void logoutWhenUsingPostLogoutRedirectUriTemplateThenBuildsItForRedirect()
+	public void logoutWhenUsingPostLogoutBaseUrlRedirectUriTemplateThenBuildsItForRedirect()
 			throws IOException, ServletException {
 			throws IOException, ServletException {
 		OAuth2AuthenticationToken token = new OAuth2AuthenticationToken(TestOidcUsers.create(),
 		OAuth2AuthenticationToken token = new OAuth2AuthenticationToken(TestOidcUsers.create(),
 				AuthorityUtils.NO_AUTHORITIES, this.registration.getRegistrationId());
 				AuthorityUtils.NO_AUTHORITIES, this.registration.getRegistrationId());
@@ -137,6 +137,36 @@ 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 logoutWhenUsingPostLogoutRedirectUriTemplateThenBuildsItForRedirect()
+			throws IOException, ServletException {
+		OAuth2AuthenticationToken token = new OAuth2AuthenticationToken(TestOidcUsers.create(),
+				AuthorityUtils.NO_AUTHORITIES, this.registration.getRegistrationId());
+		this.handler.setPostLogoutRedirectUri("{baseScheme}://{baseHost}{basePort}{basePath}");
+		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(
+				"https://endpoint?" + "id_token_hint=id-token&" + "post_logout_redirect_uri=https://rp.example.org");
+	}
+
+	@Test
+	public void logoutWhenUsingPostLogoutRedirectUriTemplateWithOtherPortThenBuildsItForRedirect()
+			throws IOException, ServletException {
+		OAuth2AuthenticationToken token = new OAuth2AuthenticationToken(TestOidcUsers.create(),
+				AuthorityUtils.NO_AUTHORITIES, this.registration.getRegistrationId());
+		this.handler.setPostLogoutRedirectUri("{baseScheme}://{baseHost}{basePort}{basePath}");
+		this.request.setScheme("https");
+		this.request.setServerPort(400);
+		this.request.setServerName("rp.example.org");
+		this.request.setUserPrincipal(token);
+		this.handler.onLogoutSuccess(this.request, this.response, token);
+		assertThat(this.response.getRedirectedUrl()).isEqualTo("https://endpoint?" + "id_token_hint=id-token&"
+				+ "post_logout_redirect_uri=https://rp.example.org:400");
+	}
+
 	@Test
 	@Test
 	public void logoutWhenUsingPostLogoutRedirectUriTemplateThenBuildsItForRedirectExpanded()
 	public void logoutWhenUsingPostLogoutRedirectUriTemplateThenBuildsItForRedirectExpanded()
 			throws IOException, ServletException {
 			throws IOException, ServletException {