Skip to content

Commit c1b3b32

Browse files
Merge branch '6.2.x' into 6.3.x
2 parents c6353d0 + 3d4bcf1 commit c1b3b32

File tree

3 files changed

+44
-7
lines changed

3 files changed

+44
-7
lines changed

config/src/main/java/org/springframework/security/config/annotation/web/configuration/HttpSecurityConfiguration.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -47,14 +47,15 @@
4747
import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter;
4848
import org.springframework.web.accept.ContentNegotiationStrategy;
4949
import org.springframework.web.accept.HeaderContentNegotiationStrategy;
50-
import org.springframework.web.cors.CorsConfigurationSource;
50+
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
5151

5252
import static org.springframework.security.config.Customizer.withDefaults;
5353

5454
/**
5555
* {@link Configuration} that exposes the {@link HttpSecurity} bean.
5656
*
5757
* @author Eleftheria Stein
58+
* @author Jinwoo Bae
5859
* @since 5.4
5960
*/
6061
@Configuration(proxyBeanMethods = false)
@@ -131,8 +132,7 @@ HttpSecurity httpSecurity() throws Exception {
131132
}
132133

133134
private void applyCorsIfAvailable(HttpSecurity http) throws Exception {
134-
String[] beanNames = this.context.getBeanNamesForType(CorsConfigurationSource.class);
135-
if (beanNames.length == 1) {
135+
if (this.context.getBeanNamesForType(UrlBasedCorsConfigurationSource.class).length > 0) {
136136
http.cors(withDefaults());
137137
}
138138
}

config/src/test/java/org/springframework/security/config/annotation/web/configuration/HttpSecurityConfigurationTests.java

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -365,7 +365,7 @@ public void disableConfigurerWhenAppliedByAnotherConfigurerThenNotApplied() {
365365
}
366366

367367
@Test
368-
public void configureWhenCorsConfigurationSourceThenApplyCors() {
368+
public void configureWhenCorsConfigurationSourceThenApplyCors() throws Exception {
369369
this.spring.register(CorsConfigurationSourceConfig.class, DefaultWithFilterChainConfig.class).autowire();
370370
SecurityFilterChain filterChain = this.spring.getContext().getBean(SecurityFilterChain.class);
371371
CorsFilter corsFilter = (CorsFilter) filterChain.getFilters()
@@ -377,6 +377,16 @@ public void configureWhenCorsConfigurationSourceThenApplyCors() {
377377
assertThat(configSource).isInstanceOf(UrlBasedCorsConfigurationSource.class);
378378
}
379379

380+
// gh-15378
381+
@Test
382+
public void configureWhenNoUrlBasedCorsConfigThenNoCorsAppliedAndVaryHeaderNotPresent() throws Exception {
383+
this.spring.register(NonUrlBasedCorsConfig.class, DefaultWithFilterChainConfig.class).autowire();
384+
SecurityFilterChain filterChain = this.spring.getContext().getBean(SecurityFilterChain.class);
385+
assertThat(filterChain.getFilters()).noneMatch((filter) -> filter instanceof CorsFilter);
386+
387+
this.mockMvc.perform(get("/")).andExpect(header().doesNotExist("Vary"));
388+
}
389+
380390
@Test
381391
public void configureWhenAddingCustomDslUsingWithThenApplied() throws Exception {
382392
this.spring.register(WithCustomDslConfig.class, UserDetailsConfig.class).autowire();
@@ -711,6 +721,33 @@ CorsConfigurationSource corsConfigurationSource() {
711721

712722
}
713723

724+
@Configuration
725+
@EnableWebSecurity
726+
static class NonUrlBasedCorsConfig {
727+
728+
@Bean
729+
CorsConfigurationSource corsConfigurationSource() {
730+
return new CustomCorsConfigurationSource();
731+
}
732+
733+
@Bean
734+
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
735+
return http.build();
736+
}
737+
738+
}
739+
740+
static class CustomCorsConfigurationSource implements CorsConfigurationSource {
741+
742+
@Override
743+
public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
744+
CorsConfiguration configuration = new CorsConfiguration();
745+
configuration.setAllowedOrigins(List.of("http://localhost:8080"));
746+
return configuration;
747+
}
748+
749+
}
750+
714751
static class DefaultConfigurer extends AbstractHttpConfigurer<DefaultConfigurer, HttpSecurity> {
715752

716753
boolean init;

docs/modules/ROOT/pages/servlet/integrations/cors.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ CORS must be processed before Spring Security, because the pre-flight request do
66
If the request does not contain any cookies and Spring Security is first, the request determines that the user is not authenticated (since there are no cookies in the request) and rejects it.
77

88
The easiest way to ensure that CORS is handled first is to use the `CorsFilter`.
9-
Users can integrate the `CorsFilter` with Spring Security by providing a `CorsConfigurationSource`.
9+
Users can integrate the `CorsFilter` with Spring Security by providing a `CorsConfigurationSource`. Note that Spring Security will automatically configure CORS only if a `UrlBasedCorsConfigurationSource` instance is present.
1010
For example, the following will integrate CORS support within Spring Security:
1111

1212
[tabs]

0 commit comments

Comments
 (0)