Auto-configure CORS options for GraphQL web endpoints
This commit adds `"spring.graphql.cors.*"` configuration properties to customize the CORS configuration for GraphQL web endpoints. See gh-29140
This commit is contained in:
@@ -34,6 +34,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.graphql.execution.RuntimeWiringConfigurer;
|
||||
import org.springframework.graphql.web.WebInterceptor;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
@@ -55,7 +56,9 @@ class GraphQlWebFluxAutoConfigurationTests {
|
||||
GraphQlWebFluxAutoConfiguration.class))
|
||||
.withUserConfiguration(DataFetchersConfiguration.class, CustomWebInterceptor.class)
|
||||
.withPropertyValues("spring.main.web-application-type=reactive", "spring.graphql.graphiql.enabled=true",
|
||||
"spring.graphql.schema.printer.enabled=true");
|
||||
"spring.graphql.schema.printer.enabled=true",
|
||||
"spring.graphql.cors.allowed-origins=https://example.com",
|
||||
"spring.graphql.cors.allowed-methods=POST", "spring.graphql.cors.allow-credentials=true");
|
||||
|
||||
@Test
|
||||
void simpleQueryShouldWork() {
|
||||
@@ -114,6 +117,19 @@ class GraphQlWebFluxAutoConfigurationTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSupportCors() {
|
||||
testWithWebClient((client) -> {
|
||||
String query = "{" + " bookById(id: \\\"book-1\\\"){ " + " id" + " name" + " pageCount"
|
||||
+ " author" + " }" + "}";
|
||||
client.post().uri("/graphql").bodyValue("{ \"query\": \"" + query + "\"}")
|
||||
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST")
|
||||
.header(HttpHeaders.ORIGIN, "https://example.com").exchange().expectStatus().isOk().expectHeader()
|
||||
.valueEquals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "https://example.com").expectHeader()
|
||||
.valueEquals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
|
||||
});
|
||||
}
|
||||
|
||||
private void testWithWebClient(Consumer<WebTestClient> consumer) {
|
||||
this.contextRunner.run((context) -> {
|
||||
WebTestClient client = WebTestClient.bindToApplicationContext(context).configureClient()
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.graphql.execution.RuntimeWiringConfigurer;
|
||||
import org.springframework.graphql.web.WebInterceptor;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
@@ -60,7 +61,9 @@ class GraphQlWebMvcAutoConfigurationTests {
|
||||
GraphQlAutoConfiguration.class, GraphQlWebMvcAutoConfiguration.class))
|
||||
.withUserConfiguration(DataFetchersConfiguration.class, CustomWebInterceptor.class)
|
||||
.withPropertyValues("spring.main.web-application-type=servlet", "spring.graphql.graphiql.enabled=true",
|
||||
"spring.graphql.schema.printer.enabled=true");
|
||||
"spring.graphql.schema.printer.enabled=true",
|
||||
"spring.graphql.cors.allowed-origins=https://example.com",
|
||||
"spring.graphql.cors.allowed-methods=POST", "spring.graphql.cors.allow-credentials=true");
|
||||
|
||||
@Test
|
||||
void simpleQueryShouldWork() {
|
||||
@@ -119,6 +122,21 @@ class GraphQlWebMvcAutoConfigurationTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSupportCors() {
|
||||
testWith((mockMvc) -> {
|
||||
String query = "{" + " bookById(id: \\\"book-1\\\"){ " + " id" + " name" + " pageCount"
|
||||
+ " author" + " }" + "}";
|
||||
MvcResult result = mockMvc.perform(post("/graphql")
|
||||
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST")
|
||||
.header(HttpHeaders.ORIGIN, "https://example.com").content("{\"query\": \"" + query + "\"}"))
|
||||
.andReturn();
|
||||
mockMvc.perform(asyncDispatch(result)).andExpect(status().isOk())
|
||||
.andExpect(header().stringValues(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "https://example.com"))
|
||||
.andExpect(header().stringValues(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true"));
|
||||
});
|
||||
}
|
||||
|
||||
private void testWith(MockMvcConsumer mockMvcConsumer) {
|
||||
this.contextRunner.run((context) -> {
|
||||
MediaType mediaType = MediaType.APPLICATION_JSON;
|
||||
|
||||
Reference in New Issue
Block a user