Ignore trailing slash in Origin header

See gh-26892
This commit is contained in:
Rossen Stoyanchev 2021-05-07 14:56:56 +01:00
parent 582b94d50e
commit dddcc5e9ad
4 changed files with 34 additions and 9 deletions

View File

@ -551,6 +551,9 @@ public class CorsConfiguration {
if (!StringUtils.hasText(requestOrigin)) { if (!StringUtils.hasText(requestOrigin)) {
return null; return null;
} }
if (requestOrigin.endsWith("/")) {
requestOrigin = requestOrigin.substring(0, requestOrigin.length() - 1);
}
if (!ObjectUtils.isEmpty(this.allowedOrigins)) { if (!ObjectUtils.isEmpty(this.allowedOrigins)) {
if (this.allowedOrigins.contains(ALL)) { if (this.allowedOrigins.contains(ALL)) {
validateAllowCredentials(); validateAllowCredentials();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2020 the original author or authors. * Copyright 2002-2021 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -291,6 +291,7 @@ public class CorsConfigurationTests {
config.setAllowedOrigins(Collections.singletonList("https://domain.com")); config.setAllowedOrigins(Collections.singletonList("https://domain.com"));
assertThat(config.checkOrigin("https://domain.com")).isEqualTo("https://domain.com"); assertThat(config.checkOrigin("https://domain.com")).isEqualTo("https://domain.com");
assertThat(config.checkOrigin("https://domain.com/")).isEqualTo("https://domain.com");
config.setAllowCredentials(false); config.setAllowCredentials(false);
assertThat(config.checkOrigin("https://domain.com")).isEqualTo("https://domain.com"); assertThat(config.checkOrigin("https://domain.com")).isEqualTo("https://domain.com");

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2020 the original author or authors. * Copyright 2002-2021 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -170,10 +170,19 @@ public class DefaultCorsProcessorTests {
this.conf.addAllowedOrigin("https://DOMAIN2.com"); this.conf.addAllowedOrigin("https://DOMAIN2.com");
this.processor.processRequest(this.conf, this.request, this.response); this.processor.processRequest(this.conf, this.request, this.response);
assertThat(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)).isTrue();
assertThat(this.response.getHeaders(HttpHeaders.VARY)).contains(HttpHeaders.ORIGIN,
HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK); assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
assertThat(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)).isTrue();
}
@Test // gh-26892
public void actualRequestTrailingSlashOriginMatch() throws Exception {
this.request.setMethod(HttpMethod.GET.name());
this.request.addHeader(HttpHeaders.ORIGIN, "https://domain2.com/");
this.conf.addAllowedOrigin("https://domain2.com");
this.processor.processRequest(this.conf, this.request, this.response);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
assertThat(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)).isTrue();
} }
@Test @Test

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2020 the original author or authors. * Copyright 2002-2021 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -172,10 +172,22 @@ public class DefaultCorsProcessorTests {
this.processor.process(this.conf, exchange); this.processor.process(this.conf, exchange);
ServerHttpResponse response = exchange.getResponse(); ServerHttpResponse response = exchange.getResponse();
assertThat(response.getHeaders().containsKey(ACCESS_CONTROL_ALLOW_ORIGIN)).isTrue();
assertThat(response.getHeaders().get(VARY)).contains(ORIGIN,
ACCESS_CONTROL_REQUEST_METHOD, ACCESS_CONTROL_REQUEST_HEADERS);
assertThat((Object) response.getStatusCode()).isNull(); assertThat((Object) response.getStatusCode()).isNull();
assertThat(response.getHeaders().containsKey(ACCESS_CONTROL_ALLOW_ORIGIN)).isTrue();
}
@Test // gh-26892
public void actualRequestTrailingSlashOriginMatch() {
ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest
.method(HttpMethod.GET, "http://localhost/test.html")
.header(HttpHeaders.ORIGIN, "https://domain2.com/"));
this.conf.addAllowedOrigin("https://domain2.com");
this.processor.process(this.conf, exchange);
ServerHttpResponse response = exchange.getResponse();
assertThat((Object) response.getStatusCode()).isNull();
assertThat(response.getHeaders().containsKey(ACCESS_CONTROL_ALLOW_ORIGIN)).isTrue();
} }
@Test @Test