Browse Source

Merge branch '6.2.x'

Josh Cummings 1 năm trước cách đây
mục cha
commit
7f0433c805

+ 9 - 4
config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OidcBackChannelLogoutHandler.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2023 the original author or authors.
+ * Copyright 2002-2024 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -106,13 +106,18 @@ final class OidcBackChannelLogoutHandler implements LogoutHandler {
 		for (Map.Entry<String, String> credential : session.getAuthorities().entrySet()) {
 			headers.add(credential.getKey(), credential.getValue());
 		}
+		String logout = computeLogoutEndpoint(request);
+		HttpEntity<?> entity = new HttpEntity<>(null, headers);
+		this.restOperations.postForEntity(logout, entity, Object.class);
+	}
+
+	String computeLogoutEndpoint(HttpServletRequest request) {
 		String url = request.getRequestURL().toString();
-		String logout = UriComponentsBuilder.fromHttpUrl(url)
+		return UriComponentsBuilder.fromHttpUrl(url)
+			.host("localhost")
 			.replacePath(this.logoutEndpointName)
 			.build()
 			.toUriString();
-		HttpEntity<?> entity = new HttpEntity<>(null, headers);
-		this.restOperations.postForEntity(logout, entity, Object.class);
 	}
 
 	private OAuth2Error oauth2Error(Collection<String> errors) {

+ 8 - 3
config/src/main/java/org/springframework/security/config/web/server/OidcBackChannelServerLogoutHandler.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2023 the original author or authors.
+ * Copyright 2002-2024 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -108,12 +108,17 @@ final class OidcBackChannelServerLogoutHandler implements ServerLogoutHandler {
 		for (Map.Entry<String, String> credential : session.getAuthorities().entrySet()) {
 			headers.add(credential.getKey(), credential.getValue());
 		}
+		String logout = computeLogoutEndpoint(exchange);
+		return this.web.post().uri(logout).headers((h) -> h.putAll(headers)).retrieve().toBodilessEntity();
+	}
+
+	String computeLogoutEndpoint(WebFilterExchange exchange) {
 		String url = exchange.getExchange().getRequest().getURI().toString();
-		String logout = UriComponentsBuilder.fromHttpUrl(url)
+		return UriComponentsBuilder.fromHttpUrl(url)
+			.host("localhost")
 			.replacePath(this.logoutEndpointName)
 			.build()
 			.toUriString();
-		return this.web.post().uri(logout).headers((h) -> h.putAll(headers)).retrieve().toBodilessEntity();
 	}
 
 	private OAuth2Error oauth2Error(Collection<?> errors) {

+ 38 - 0
config/src/test/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OidcBackChannelLogoutHandlerTests.java

@@ -0,0 +1,38 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.config.annotation.web.configurers.oauth2.client;
+
+import org.junit.jupiter.api.Test;
+
+import org.springframework.mock.web.MockHttpServletRequest;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class OidcBackChannelLogoutHandlerTests {
+
+	// gh-14553
+	@Test
+	public void computeLogoutEndpointWhenDifferentHostnameThenLocalhost() {
+		OidcBackChannelLogoutHandler logoutHandler = new OidcBackChannelLogoutHandler();
+		MockHttpServletRequest request = new MockHttpServletRequest("GET", "/back-channel/logout");
+		request.setRemoteHost("host.docker.internal");
+		request.setServerPort(8090);
+		String endpoint = logoutHandler.computeLogoutEndpoint(request);
+		assertThat(endpoint).isEqualTo("http://localhost:8090/logout");
+	}
+
+}

+ 46 - 0
config/src/test/java/org/springframework/security/config/web/server/OidcBackChannelServerLogoutHandlerTests.java

@@ -0,0 +1,46 @@
+/*
+ * Copyright 2002-2024 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.config.web.server;
+
+import org.junit.jupiter.api.Test;
+import reactor.core.publisher.Mono;
+
+import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
+import org.springframework.mock.web.server.MockServerWebExchange;
+import org.springframework.security.web.server.WebFilterExchange;
+import org.springframework.web.server.ServerWebExchange;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@link OidcBackChannelServerLogoutHandler}
+ */
+public class OidcBackChannelServerLogoutHandlerTests {
+
+	// gh-14553
+	@Test
+	public void computeLogoutEndpointWhenDifferentHostnameThenLocalhost() {
+		OidcBackChannelServerLogoutHandler logoutHandler = new OidcBackChannelServerLogoutHandler();
+		MockServerHttpRequest request = MockServerHttpRequest
+			.get("https://host.docker.internal:8090/back-channel/logout")
+			.build();
+		ServerWebExchange exchange = new MockServerWebExchange.Builder(request).build();
+		String endpoint = logoutHandler.computeLogoutEndpoint(new WebFilterExchange(exchange, (ex) -> Mono.empty()));
+		assertThat(endpoint).isEqualTo("https://localhost:8090/logout");
+	}
+
+}