Migrate CorsConfigurerTests groovy->java

Issue: gh-4939
This commit is contained in:
Eleftheria Stein 2019-06-03 15:37:34 -04:00 committed by Eleftheria Stein-Kousathana
parent c4dd800653
commit 371a3b9c7f
2 changed files with 231 additions and 201 deletions

View File

@ -1,201 +0,0 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.config.annotation.web.configurers
import org.springframework.beans.factory.BeanCreationException
import org.springframework.beans.factory.NoSuchBeanDefinitionException
import javax.servlet.http.HttpServletResponse
import org.springframework.context.annotation.Bean
import org.springframework.http.*
import org.springframework.security.config.annotation.BaseSpringSpec
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
import org.springframework.web.bind.annotation.*
import org.springframework.web.cors.CorsConfiguration
import org.springframework.web.cors.CorsConfigurationSource
import org.springframework.web.cors.UrlBasedCorsConfigurationSource
import org.springframework.web.filter.CorsFilter
import org.springframework.web.servlet.config.annotation.EnableWebMvc
/**
*
* @author Rob Winch
*/
class CorsConfigurerTests extends BaseSpringSpec {
def "No MVC throws meaningful error"() {
when:
loadConfig(DefaultCorsConfig)
then:
BeanCreationException success = thrown()
success.message.contains("Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext")
}
@EnableWebSecurity
static class DefaultCorsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.cors()
}
}
def "HandlerMappingIntrospector explicit"() {
setup:
loadConfig(MvcCorsConfig)
when:
addCors()
springSecurityFilterChain.doFilter(request,response,chain)
then: 'Ensure we a CORS response w/ Spring Security headers too'
responseHeaders['Access-Control-Allow-Origin']
responseHeaders['X-Content-Type-Options']
when:
setupWeb()
addCors(true)
springSecurityFilterChain.doFilter(request,response,chain)
then: 'Ensure we a CORS response w/ Spring Security headers too'
responseHeaders['Access-Control-Allow-Origin']
responseHeaders['X-Content-Type-Options']
response.status == HttpServletResponse.SC_OK
}
@EnableWebMvc
@EnableWebSecurity
static class MvcCorsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.cors()
}
@RestController
@CrossOrigin(methods = [
RequestMethod.GET, RequestMethod.POST
])
static class CorsController {
@RequestMapping("/")
String hello() {
"Hello"
}
}
}
def "CorsConfigurationSource"() {
setup:
loadConfig(ConfigSourceConfig)
when:
addCors()
springSecurityFilterChain.doFilter(request,response,chain)
then: 'Ensure we a CORS response w/ Spring Security headers too'
responseHeaders['Access-Control-Allow-Origin']
responseHeaders['X-Content-Type-Options']
when:
setupWeb()
addCors(true)
springSecurityFilterChain.doFilter(request,response,chain)
then: 'Ensure we a CORS response w/ Spring Security headers too'
responseHeaders['Access-Control-Allow-Origin']
responseHeaders['X-Content-Type-Options']
response.status == HttpServletResponse.SC_OK
}
@EnableWebSecurity
static class ConfigSourceConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.cors()
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource()
source.registerCorsConfiguration("/**", new CorsConfiguration(allowedOrigins : ['*'], allowedMethods : [
RequestMethod.GET.name(),
RequestMethod.POST.name()
]))
source
}
}
def "CorsFilter"() {
setup:
loadConfig(CorsFilterConfig)
when:
addCors()
springSecurityFilterChain.doFilter(request,response,chain)
then: 'Ensure we a CORS response w/ Spring Security headers too'
responseHeaders['Access-Control-Allow-Origin']
responseHeaders['X-Content-Type-Options']
when:
setupWeb()
addCors(true)
springSecurityFilterChain.doFilter(request,response,chain)
then: 'Ensure we a CORS response w/ Spring Security headers too'
responseHeaders['Access-Control-Allow-Origin']
responseHeaders['X-Content-Type-Options']
response.status == HttpServletResponse.SC_OK
}
@EnableWebSecurity
static class CorsFilterConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.cors()
}
@Bean
CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource()
source.registerCorsConfiguration("/**", new CorsConfiguration(allowedOrigins : ['*'], allowedMethods : [
RequestMethod.GET.name(),
RequestMethod.POST.name()
]))
new CorsFilter(source)
}
}
def addCors(boolean isPreflight=false) {
request.addHeader(HttpHeaders.ORIGIN,"https://example.com")
if(!isPreflight) {
return
}
request.method = HttpMethod.OPTIONS.name()
request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpMethod.POST.name())
}
}

View File

@ -0,0 +1,231 @@
/*
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.config.annotation.web.configurers;
import com.google.common.net.HttpHeaders;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.test.SpringTestRule;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import java.util.Arrays;
import java.util.Collections;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
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;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link CorsConfigurer}
*
* @author Rob Winch
* @author Eleftheria Stein
*/
public class CorsConfigurerTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@Autowired
MockMvc mvc;
@Test
public void configureWhenNoMvcThenException() {
assertThatThrownBy(() -> this.spring.register(DefaultCorsConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasMessageContaining("Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext");
}
@EnableWebSecurity
static class DefaultCorsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.cors();
// @formatter:on
}
}
@Test
public void getWhenCrossOriginAnnotationThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(MvcCorsConfig.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 optionsWhenCrossOriginAnnotationThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(MvcCorsConfig.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 MvcCorsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.cors();
// @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();
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 optionsWhenCorsConfigurationSourceBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(ConfigSourceConfig.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 ConfigSourceConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.cors();
// @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();
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 optionsWhenCorsFilterBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(CorsFilterConfig.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 CorsFilterConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.cors();
// @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);
}
}
}