Skip to content

Commit 90de1ab

Browse files
GungnirLaevatainsbrannen
authored andcommitted
Ensure local @crossorigin maxAge overrides global value
Prior to this commit, a method-level @crossorigin maxAge value did not override a class-level @crossorigin maxAge value. This contradicts the Javadoc for @Crossorgin which states the following. For those attributes where only a single value can be accepted such as allowCredentials and maxAge, the local overrides the global value. This commit ensures that a method-level @crossorigin maxAge value overrides a class-level @crossorigin maxAge value. Closes gh-26619
1 parent 5a11569 commit 90de1ab

File tree

4 files changed

+69
-2
lines changed

4 files changed

+69
-2
lines changed

spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ else if (!allowCredentials.isEmpty()) {
341341
"or an empty string (\"\"): current value is [" + allowCredentials + "]");
342342
}
343343

344-
if (annotation.maxAge() >= 0 && config.getMaxAge() == null) {
344+
if (annotation.maxAge() >= 0) {
345345
config.setMaxAge(annotation.maxAge());
346346
}
347347
}

spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/CrossOriginAnnotationIntegrationTests.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.springframework.http.HttpStatus;
3030
import org.springframework.http.ResponseEntity;
3131
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
32+
import org.springframework.stereotype.Controller;
3233
import org.springframework.web.bind.annotation.CrossOrigin;
3334
import org.springframework.web.bind.annotation.GetMapping;
3435
import org.springframework.web.bind.annotation.PostMapping;
@@ -37,6 +38,7 @@
3738
import org.springframework.web.bind.annotation.RestController;
3839
import org.springframework.web.client.HttpClientErrorException;
3940
import org.springframework.web.client.RestTemplate;
41+
import org.springframework.web.cors.CorsConfiguration;
4042
import org.springframework.web.reactive.config.EnableWebFlux;
4143
import org.springframework.web.testfixture.http.server.reactive.bootstrap.HttpServer;
4244

@@ -278,6 +280,19 @@ void ambiguousProducesPreflightRequest(HttpServer httpServer) throws Exception {
278280
assertThat(entity.getHeaders().getAccessControlAllowCredentials()).isTrue();
279281
}
280282

283+
@ParameterizedHttpServerTest
284+
void maxAgeWithDefaultOrigin(HttpServer httpServer) throws Exception {
285+
startServer(httpServer);
286+
287+
this.headers.add(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET");
288+
ResponseEntity<String> entity = performOptions("/classAge", this.headers, String.class);
289+
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
290+
assertThat(entity.getHeaders().getAccessControlMaxAge()).isEqualTo(10);
291+
292+
entity = performOptions("/methodAge", this.headers, String.class);
293+
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
294+
assertThat(entity.getHeaders().getAccessControlMaxAge()).isEqualTo(100);
295+
}
281296

282297
@Configuration
283298
@EnableWebFlux
@@ -395,4 +410,21 @@ public String baz() {
395410
}
396411
}
397412

413+
@RestController
414+
@CrossOrigin(maxAge = 10)
415+
private static class MaxAgeWithDefaultOriginController {
416+
417+
@CrossOrigin
418+
@GetMapping(path = "/classAge")
419+
public String classAge() {
420+
return "classAge";
421+
}
422+
423+
@CrossOrigin(maxAge = 100)
424+
@GetMapping(path = "/methodAge")
425+
public String methodAge() {
426+
return "methodAge";
427+
}
428+
}
429+
398430
}

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ else if (!allowCredentials.isEmpty()) {
476476
"or an empty string (\"\"): current value is [" + allowCredentials + "]");
477477
}
478478

479-
if (annotation.maxAge() >= 0 && config.getMaxAge() == null) {
479+
if (annotation.maxAge() >= 0 ) {
480480
config.setMaxAge(annotation.maxAge());
481481
}
482482
}

spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/CrossOriginTests.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,27 @@ void preFlightRequestWithoutRequestMethodHeader(TestRequestMappingInfoHandlerMap
362362
assertThat(mapping.getHandler(request)).isNull();
363363
}
364364

365+
@PathPatternsParameterizedTest
366+
void maxAgeWithDefaultOrigin(TestRequestMappingInfoHandlerMapping mapping) throws Exception {
367+
mapping.registerHandler(new MaxAgeWithDefaultOriginController());
368+
369+
this.request.setRequestURI("/classAge");
370+
HandlerExecutionChain chain = mapping.getHandler(request);
371+
CorsConfiguration config = getCorsConfiguration(chain, false);
372+
assertThat(config).isNotNull();
373+
assertThat(config.getAllowedMethods()).containsExactly("GET");
374+
assertThat(config.getAllowedOrigins()).containsExactly("*");
375+
assertThat(config.getMaxAge()).isEqualTo(10);
376+
377+
this.request.setRequestURI("/methodAge");
378+
chain = mapping.getHandler(request);
379+
config = getCorsConfiguration(chain, false);
380+
assertThat(config).isNotNull();
381+
assertThat(config.getAllowedMethods()).containsExactly("GET");
382+
assertThat(config.getAllowedOrigins()).containsExactly("*");
383+
assertThat(config.getMaxAge()).isEqualTo(100);
384+
}
385+
365386

366387
@Nullable
367388
private CorsConfiguration getCorsConfiguration(@Nullable HandlerExecutionChain chain, boolean isPreFlightRequest) {
@@ -490,6 +511,20 @@ public void baz() {
490511
}
491512
}
492513

514+
@Controller
515+
@CrossOrigin(maxAge = 10)
516+
private static class MaxAgeWithDefaultOriginController {
517+
518+
@CrossOrigin
519+
@RequestMapping(path = "/classAge", method = RequestMethod.GET)
520+
public void classAge() {
521+
}
522+
523+
@CrossOrigin(maxAge = 100)
524+
@RequestMapping(path = "/methodAge", method = RequestMethod.GET)
525+
public void methodAge() {
526+
}
527+
}
493528

494529
@Controller
495530
@CrossOrigin(allowCredentials = "true")

0 commit comments

Comments
 (0)