Im trying to write a test to verify our CORS settings. I configure CORS like this.
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
// super.configure(httpSecurity);
httpSecurity.csrf().disable();
httpSecurity.authorizeRequests().antMatchers("/**").permitAll();
httpSecurity.cors();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
List<String> allowedMethods = CORS_ALLOWED_METHODS;
configuration.setAllowedMethods(allowedMethods);
configuration.setAllowedOrigins(CORS_ALLOWED_ORIGINS);
configuration.setAllowedHeaders(CORS_ALLOWED_HEADERS);
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
I have verified with the debugger that CORS_ALLOWED_METHODS
has values when my test runs.
Here is my test. It fails when I assert on the headers.
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("dev")
public class ControllerTests {
@Autowired
private WebApplicationContext wac;
public MockMvc mockMvc;
@Before
public void setup() {
DefaultMockMvcBuilder builder = MockMvcBuilders
.webAppContextSetup(this.wac)
.apply(SecurityMockMvcConfigurers.springSecurity())
.dispatchOptions(true);
this.mockMvc = builder.build();
}
@Test
public void testCors() throws Exception {
this.mockMvc
.perform(get("/test-cors"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(header().string("Access-Control-Allow-Methods", "OPTIONS,GET,HEAD,POST,PUT,DELETE,TRACE,CONNECT"))
.andExpect(content().string("whatever"));
}
@SpringBootApplication(scanBasePackages = {"the.packages"})
@Controller
static class TestApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(TestApplication.class, args);
}
@RequestMapping(value = {"test-cors"}, method = RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
public @ResponseBody String testCors() {
return "whatever";
}
}
}
As a note, when I actually run a SpringBoot app with this configuration we do get CORS headers.
Any help appreciated.
The CORS request needs to include an Origin
header for the server to process it. The mock GET request is not having this header. The API does allow us to include headers in the mock requests.
public MockHttpServletRequestBuilder header(String name, Object... values)
Add a header to the request. Values are always added. Parameters: name - the header name values - one or more header values
Here is the code that works
.perform(options("/test-cors")
.header("Access-Control-Request-Method", "GET")
.header("Origin", "http://www.someurl.com"))
Both headers are required, and the configuration
requires that allowed origins and methods align with the values passed in the test.