Skip to content

Commit e8f685e

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 428dbc4 commit e8f685e

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ else if (!allowCredentials.isEmpty()) {
338338
"or an empty string (\"\"): current value is [" + allowCredentials + "]");
339339
}
340340

341-
if (annotation.maxAge() >= 0 && config.getMaxAge() == null) {
341+
if (annotation.maxAge() >= 0) {
342342
config.setMaxAge(annotation.maxAge());
343343
}
344344
}

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

+32
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

@@ -257,6 +259,19 @@ void ambiguousProducesPreflightRequest(HttpServer httpServer) throws Exception {
257259
assertThat(entity.getHeaders().getAccessControlAllowCredentials()).isTrue();
258260
}
259261

262+
@ParameterizedHttpServerTest
263+
void maxAgeWithDefaultOrigin(HttpServer httpServer) throws Exception {
264+
startServer(httpServer);
265+
266+
this.headers.add(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET");
267+
ResponseEntity<String> entity = performOptions("/classAge", this.headers, String.class);
268+
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
269+
assertThat(entity.getHeaders().getAccessControlMaxAge()).isEqualTo(10);
270+
271+
entity = performOptions("/methodAge", this.headers, String.class);
272+
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
273+
assertThat(entity.getHeaders().getAccessControlMaxAge()).isEqualTo(100);
274+
}
260275

261276
@Configuration
262277
@EnableWebFlux
@@ -361,4 +376,21 @@ public String baz() {
361376
}
362377
}
363378

379+
@RestController
380+
@CrossOrigin(maxAge = 10)
381+
private static class MaxAgeWithDefaultOriginController {
382+
383+
@CrossOrigin
384+
@GetMapping(path = "/classAge")
385+
public String classAge() {
386+
return "classAge";
387+
}
388+
389+
@CrossOrigin(maxAge = 100)
390+
@GetMapping(path = "/methodAge")
391+
public String methodAge() {
392+
return "methodAge";
393+
}
394+
}
395+
364396
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ else if (!allowCredentials.isEmpty()) {
456456
"or an empty string (\"\"): current value is [" + allowCredentials + "]");
457457
}
458458

459-
if (annotation.maxAge() >= 0 && config.getMaxAge() == null) {
459+
if (annotation.maxAge() >= 0) {
460460
config.setMaxAge(annotation.maxAge());
461461
}
462462
}

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

+35
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,27 @@ public void preFlightRequestWithoutRequestMethodHeader() throws Exception {
310310
assertThat(this.handlerMapping.getHandler(request)).isNull();
311311
}
312312

313+
@Test
314+
public void maxAgeWithDefaultOrigin() throws Exception {
315+
this.handlerMapping.registerHandler(new MaxAgeWithDefaultOriginController());
316+
317+
this.request.setRequestURI("/classAge");
318+
HandlerExecutionChain chain = this.handlerMapping.getHandler(request);
319+
CorsConfiguration config = getCorsConfiguration(chain, false);
320+
assertThat(config).isNotNull();
321+
assertThat(config.getAllowedMethods()).containsExactly("GET");
322+
assertThat(config.getAllowedOrigins()).containsExactly("*");
323+
assertThat(config.getMaxAge()).isEqualTo(10);
324+
325+
this.request.setRequestURI("/methodAge");
326+
chain = this.handlerMapping.getHandler(request);
327+
config = getCorsConfiguration(chain, false);
328+
assertThat(config).isNotNull();
329+
assertThat(config.getAllowedMethods()).containsExactly("GET");
330+
assertThat(config.getAllowedOrigins()).containsExactly("*");
331+
assertThat(config.getMaxAge()).isEqualTo(100);
332+
}
333+
313334

314335
private CorsConfiguration getCorsConfiguration(HandlerExecutionChain chain, boolean isPreFlightRequest) {
315336
if (isPreFlightRequest) {
@@ -425,7 +446,21 @@ public void bar() {
425446
@RequestMapping(path = "/baz", method = RequestMethod.GET)
426447
public void baz() {
427448
}
449+
}
450+
451+
@Controller
452+
@CrossOrigin(maxAge = 10)
453+
private static class MaxAgeWithDefaultOriginController {
428454

455+
@CrossOrigin
456+
@RequestMapping(path = "/classAge", method = RequestMethod.GET)
457+
public void classAge() {
458+
}
459+
460+
@CrossOrigin(maxAge = 100)
461+
@RequestMapping(path = "/methodAge", method = RequestMethod.GET)
462+
public void methodAge() {
463+
}
429464
}
430465

431466

0 commit comments

Comments
 (0)