mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-27 14:22:47 +00:00
Migrate CorsConfigurerTests groovy->java
Issue: gh-4939
This commit is contained in:
parent
c4dd800653
commit
371a3b9c7f
@ -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())
|
|
||||||
}
|
|
||||||
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user