Skip to content
This repository was archived by the owner on Dec 19, 2023. It is now read-only.

Commit e4bb148

Browse files
committed
Set default cors headers if missing fix #498
1 parent f834807 commit e4bb148

File tree

5 files changed

+82
-6
lines changed

5 files changed

+82
-6
lines changed

graphql-spring-boot-autoconfigure/src/main/java/graphql/kickstart/spring/web/boot/GraphQLInstrumentationAutoConfiguration.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
1818
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
1919
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
20-
import org.springframework.boot.context.properties.EnableConfigurationProperties;
2120
import org.springframework.context.annotation.Bean;
2221
import org.springframework.context.annotation.Configuration;
2322

@@ -30,7 +29,6 @@
3029
@AutoConfigureAfter({MetricsAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class,
3130
GraphQLWebsocketAutoConfiguration.class})
3231
@ConditionalOnProperty(value = "graphql.servlet.enabled", havingValue = "true", matchIfMissing = true)
33-
@EnableConfigurationProperties({GraphQLServletProperties.class})
3432
public class GraphQLInstrumentationAutoConfiguration {
3533

3634
private final GraphQLServletProperties graphqlServletProperties;

graphql-spring-boot-autoconfigure/src/main/java/graphql/kickstart/spring/web/boot/GraphQLWebAutoConfiguration.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import graphql.kickstart.spring.web.boot.metrics.MetricsInstrumentation;
5757
import graphql.kickstart.tools.boot.GraphQLJavaToolsAutoConfiguration;
5858
import graphql.schema.GraphQLSchema;
59+
import java.util.Arrays;
5960
import java.util.LinkedHashMap;
6061
import java.util.List;
6162
import java.util.Map;
@@ -78,6 +79,7 @@
7879
import org.springframework.context.annotation.Bean;
7980
import org.springframework.context.annotation.Conditional;
8081
import org.springframework.context.annotation.Configuration;
82+
import org.springframework.http.HttpMethod;
8183
import org.springframework.web.cors.CorsConfiguration;
8284
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
8385
import org.springframework.web.filter.CorsFilter;
@@ -126,6 +128,10 @@ public CorsConfiguration corsConfiguration() {
126128
@ConditionalOnProperty(value = "graphql.servlet.corsEnabled", havingValue = "true", matchIfMissing = true)
127129
public CorsFilter corsConfigurer(CorsConfiguration corsConfiguration) {
128130
Map<String, CorsConfiguration> corsConfigurations = new LinkedHashMap<>(1);
131+
if (corsConfiguration.getAllowedMethods() == null) {
132+
corsConfiguration.setAllowedMethods(
133+
Arrays.asList(HttpMethod.GET.name(), HttpMethod.HEAD.name(), HttpMethod.POST.name()));
134+
}
129135
corsConfigurations.put(graphQLServletProperties.getCorsMapping(), corsConfiguration);
130136

131137
UrlBasedCorsConfigurationSource configurationSource = new UrlBasedCorsConfigurationSource();
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package graphql.kickstart.spring.web.boot;
2+
3+
import static graphql.Scalars.GraphQLString;
4+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.options;
5+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
6+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
7+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
8+
9+
import graphql.schema.GraphQLFieldDefinition;
10+
import graphql.schema.GraphQLObjectType;
11+
import graphql.schema.GraphQLSchema;
12+
import org.junit.jupiter.api.Test;
13+
import org.junit.jupiter.api.extension.ExtendWith;
14+
import org.springframework.beans.factory.annotation.Autowired;
15+
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
16+
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
17+
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
18+
import org.springframework.boot.test.context.SpringBootTest;
19+
import org.springframework.boot.test.context.TestConfiguration;
20+
import org.springframework.context.annotation.Bean;
21+
import org.springframework.http.MediaType;
22+
import org.springframework.test.context.junit.jupiter.SpringExtension;
23+
import org.springframework.test.web.servlet.MockMvc;
24+
import org.springframework.test.web.servlet.ResultActions;
25+
26+
@ExtendWith(SpringExtension.class)
27+
@AutoConfigureMockMvc
28+
@ImportAutoConfiguration({JacksonAutoConfiguration.class, GraphQLWebAutoConfiguration.class})
29+
@SpringBootTest(properties = {"debug=true", "graphql.servlet.mapping=/graphql", "graphql.servlet.cors.allowed-origins=https://trusted.com", "graphql.servlet.cors.allowed-methods=GET,HEAD,POST"})
30+
class CorsTest {
31+
32+
@Autowired
33+
private MockMvc mockMvc;
34+
35+
@Test
36+
void evilDomain_shouldNotBeAllowed() throws Exception {
37+
ResultActions resultActions = performCorsPreflight("https://evil.com");
38+
resultActions
39+
.andExpect(status().isForbidden())
40+
.andExpect(content().string("Invalid CORS request"));
41+
}
42+
43+
private ResultActions performCorsPreflight(String origin) throws Exception {
44+
return mockMvc.perform(
45+
options("/graphql")
46+
.contentType(MediaType.APPLICATION_JSON)
47+
.header("Access-Control-Request-Method", "POST")
48+
.header("Origin", origin)
49+
);
50+
}
51+
52+
@Test
53+
void trustedDomain_shouldBeAllowed() throws Exception {
54+
ResultActions resultActions = performCorsPreflight("https://trusted.com");
55+
resultActions
56+
.andExpect(status().isOk())
57+
.andExpect(header().string("Access-Control-Allow-Origin", "https://trusted.com"))
58+
.andExpect(header().string("Access-Control-Allow-Methods", "GET,HEAD,POST"));
59+
}
60+
61+
@TestConfiguration
62+
static class MyTestConfiguration {
63+
64+
@Bean
65+
public GraphQLSchema graphQLSchema() {
66+
return GraphQLSchema.newSchema()
67+
.query(GraphQLObjectType.newObject().name("Query").field(
68+
GraphQLFieldDefinition.newFieldDefinition()
69+
.name("echo")
70+
.type(GraphQLString)
71+
.build()).build()).build();
72+
}
73+
}
74+
75+
}

graphql-spring-boot-autoconfigure/src/test/java/graphql/kickstart/spring/web/boot/GraphQLServletPropertiesTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"graphql.servlet.contextSetting=PER_REQUEST_WITH_INSTRUMENTATION"})
1616
class GraphQLServletPropertiesTest {
1717

18+
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
1819
@Autowired
1920
private GraphQLServletProperties properties;
2021

graphql-spring-boot-autoconfigure/src/test/java/graphql/kickstart/spring/web/boot/TestAutoConfiguration.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
package graphql.kickstart.spring.web.boot;
22

33
import org.springframework.boot.SpringBootConfiguration;
4-
import org.springframework.boot.context.properties.EnableConfigurationProperties;
5-
import org.springframework.context.annotation.Import;
64

75
@SpringBootConfiguration
8-
@Import(GraphQLServletProperties.class)
9-
@EnableConfigurationProperties
106
public class TestAutoConfiguration {
117

128

0 commit comments

Comments
 (0)