Allow configuration of cors through nested builder

Issue: gh-5557
This commit is contained in:
Eleftheria Stein 2019-06-27 15:07:41 -04:00
parent a9a1f8ee53
commit 6fd515813c
2 changed files with 180 additions and 0 deletions

View File

@ -448,6 +448,36 @@ public final class HttpSecurity extends
return getOrApply(new CorsConfigurer<>());
}
/**
* Adds a {@link CorsFilter} to be used. If a bean by the name of corsFilter is
* provided, that {@link CorsFilter} is used. Else if corsConfigurationSource is
* defined, then that {@link CorsConfiguration} is used. Otherwise, if Spring MVC is
* on the classpath a {@link HandlerMappingIntrospector} is used.
* You can enable CORS using:
*
* <pre>
* &#064;Configuration
* &#064;EnableWebSecurity
* public class CorsSecurityConfig extends WebSecurityConfigurerAdapter {
*
* &#064;Override
* protected void configure(HttpSecurity http) throws Exception {
* http
* .cors(withDefaults());
* }
* }
* </pre>
*
* @param corsCustomizer the {@link Customizer} to provide more options for
* the {@link CorsConfigurer}
* @return the {@link HttpSecurity} for further customizations
* @throws Exception
*/
public HttpSecurity cors(Customizer<CorsConfigurer<HttpSecurity>> corsCustomizer) throws Exception {
corsCustomizer.customize(getOrApply(new CorsConfigurer<>()));
return HttpSecurity.this;
}
/**
* Allows configuring of Session Management.
*

View File

@ -42,6 +42,7 @@ import java.util.Arrays;
import java.util.Collections;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.springframework.security.config.Customizer.withDefaults;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.options;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
@ -131,6 +132,55 @@ public class CorsConfigurerTests {
}
}
@Test
public void getWhenDefaultsInLambdaAndCrossOriginAnnotationThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(MvcCorsInLambdaConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@Test
public void optionsWhenDefaultsInLambdaAndCrossOriginAnnotationThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(MvcCorsInLambdaConfig.class).autowire();
this.mvc.perform(options("/")
.header(org.springframework.http.HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpMethod.POST.name())
.header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(status().isOk())
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@EnableWebMvc
@EnableWebSecurity
static class MvcCorsInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.cors(withDefaults());
// @formatter:on
}
@RestController
@CrossOrigin(methods = {
RequestMethod.GET, RequestMethod.POST
})
static class CorsController {
@RequestMapping("/")
String hello() {
return "Hello";
}
}
}
@Test
public void getWhenCorsConfigurationSourceBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(ConfigSourceConfig.class).autowire();
@ -180,6 +230,57 @@ public class CorsConfigurerTests {
}
}
@Test
public void getWhenMvcCorsInLambdaConfigAndCorsConfigurationSourceBeanThenRespondsWithCorsHeaders()
throws Exception {
this.spring.register(ConfigSourceInLambdaConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@Test
public void optionsWhenMvcCorsInLambdaConfigAndCorsConfigurationSourceBeanThenRespondsWithCorsHeaders()
throws Exception {
this.spring.register(ConfigSourceInLambdaConfig.class).autowire();
this.mvc.perform(options("/")
.header(org.springframework.http.HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpMethod.POST.name())
.header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(status().isOk())
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@EnableWebSecurity
static class ConfigSourceInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.cors(withDefaults());
// @formatter:on
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedOrigins(Collections.singletonList("*"));
corsConfiguration.setAllowedMethods(Arrays.asList(
RequestMethod.GET.name(),
RequestMethod.POST.name()));
source.registerCorsConfiguration("/**", corsConfiguration);
return source;
}
}
@Test
public void getWhenCorsFilterBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(CorsFilterConfig.class).autowire();
@ -228,4 +329,53 @@ public class CorsConfigurerTests {
return new CorsFilter(source);
}
}
@Test
public void getWhenConfigSourceInLambdaConfigAndCorsFilterBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(CorsFilterInLambdaConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@Test
public void optionsWhenConfigSourceInLambdaConfigAndCorsFilterBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(CorsFilterInLambdaConfig.class).autowire();
this.mvc.perform(options("/")
.header(org.springframework.http.HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpMethod.POST.name())
.header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(status().isOk())
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@EnableWebSecurity
static class CorsFilterInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.cors(withDefaults());
// @formatter:on
}
@Bean
CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedOrigins(Collections.singletonList("*"));
corsConfiguration.setAllowedMethods(Arrays.asList(
RequestMethod.GET.name(),
RequestMethod.POST.name()));
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(source);
}
}
}