mirror of
https://github.com/spring-projects/spring-boot.git
synced 2026-09-17 12:09:16 +00:00
Strip query string from Cloud Foundry reactive links base URL
CloudFoundryLinksHandler passes request.getURI().toString() directly to EndpointLinksResolver.resolveLinks(), which includes the query string. This causes generated link hrefs to contain the query (for example, "/cfApplication?x=1/info"). The standard WebFlux and Cloud Foundry servlet siblings already strip the query before resolving links. Use UriComponentsBuilder.replaceQuery(null) to match the pattern used by WebFluxEndpointHandlerMapping and add a regression test for a query-string request. Signed-off-by: Lee JiWon <dlwldnjs1009@gmail.com> See gh-50008
This commit is contained in:
committed by
Andy Wilkinson
parent
c9f9c45a2d
commit
847b2e837b
+3
-1
@@ -49,6 +49,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.reactive.result.method.RequestMappingInfoHandlerMapping;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
/**
|
||||
* A custom {@link RequestMappingInfoHandlerMapping} that makes web endpoints available on
|
||||
@@ -110,8 +111,9 @@ class CloudFoundryWebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointH
|
||||
return new ResponseEntity<>(securityResponse.getStatus());
|
||||
}
|
||||
AccessLevel accessLevel = exchange.getAttribute(AccessLevel.REQUEST_ATTRIBUTE);
|
||||
String requestUri = UriComponentsBuilder.fromUri(request.getURI()).replaceQuery(null).toUriString();
|
||||
Map<String, Link> links = CloudFoundryWebFluxEndpointHandlerMapping.this.linksResolver
|
||||
.resolveLinks(request.getURI().toString());
|
||||
.resolveLinks(requestUri);
|
||||
return new ResponseEntity<>(
|
||||
Collections.singletonMap("_links", getAccessibleLinks(accessLevel, links)), HttpStatus.OK);
|
||||
});
|
||||
|
||||
+21
@@ -61,6 +61,7 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
@@ -166,6 +167,26 @@ class CloudFoundryWebFluxEndpointIntegrationTests {
|
||||
.isEqualTo(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void linksToOtherEndpointsWithQueryStringShouldNotContainQueryInHref() {
|
||||
given(this.tokenValidator.validate(any())).willReturn(Mono.empty());
|
||||
given(this.securityService.getAccessLevel(any(), eq("app-id"))).willReturn(Mono.just(AccessLevel.FULL));
|
||||
this.contextRunner.run(withWebTestClient((client) -> client.get()
|
||||
.uri("/cfApplication?x=1")
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.header("Authorization", "bearer " + mockAccessToken())
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk()
|
||||
.expectBody()
|
||||
.jsonPath("_links.self.href")
|
||||
.value((href) -> assertThat((String) href).doesNotContain("?").endsWith("/cfApplication"))
|
||||
.jsonPath("_links.info.href")
|
||||
.value((href) -> assertThat((String) href).doesNotContain("?").endsWith("/cfApplication/info"))
|
||||
.jsonPath("_links.env.href")
|
||||
.value((href) -> assertThat((String) href).doesNotContain("?").endsWith("/cfApplication/env"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
void linksToOtherEndpointsForbidden() {
|
||||
CloudFoundryAuthorizationException exception = new CloudFoundryAuthorizationException(Reason.INVALID_TOKEN,
|
||||
|
||||
Reference in New Issue
Block a user