Skip to content

Commit dc4e053

Browse files
committed
CorsConfiguration ignores trailing "/" in pattern
Recent commit dddcc5e ensured a trailing "/" in the Origin header has no effect. This commit does the same for a trailing "/" in configured patterns. See gh-26892
1 parent 07ba957 commit dc4e053

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,12 @@ public CorsConfiguration(CorsConfiguration other) {
138138
* {@code @CrossOrigin}, via {@link #applyPermitDefaultValues()}.
139139
*/
140140
public void setAllowedOrigins(@Nullable List<String> allowedOrigins) {
141-
this.allowedOrigins = (allowedOrigins != null ? new ArrayList<>(allowedOrigins) : null);
141+
this.allowedOrigins = (allowedOrigins != null ?
142+
allowedOrigins.stream().map(this::trimTrailingSlash).collect(Collectors.toList()) : null);
143+
}
144+
145+
private String trimTrailingSlash(String origin) {
146+
return origin.endsWith("/") ? origin.substring(0, origin.length() - 1) : origin;
142147
}
143148

144149
/**
@@ -159,6 +164,7 @@ public void addAllowedOrigin(String origin) {
159164
else if (this.allowedOrigins == DEFAULT_PERMIT_ALL && CollectionUtils.isEmpty(this.allowedOriginPatterns)) {
160165
setAllowedOrigins(DEFAULT_PERMIT_ALL);
161166
}
167+
origin = trimTrailingSlash(origin);
162168
this.allowedOrigins.add(origin);
163169
}
164170

@@ -209,6 +215,7 @@ public void addAllowedOriginPattern(String originPattern) {
209215
if (this.allowedOriginPatterns == null) {
210216
this.allowedOriginPatterns = new ArrayList<>(4);
211217
}
218+
originPattern = trimTrailingSlash(originPattern);
212219
this.allowedOriginPatterns.add(new OriginPattern(originPattern));
213220
if (this.allowedOrigins == DEFAULT_PERMIT_ALL) {
214221
this.allowedOrigins = null;
@@ -551,9 +558,7 @@ public String checkOrigin(@Nullable String requestOrigin) {
551558
if (!StringUtils.hasText(requestOrigin)) {
552559
return null;
553560
}
554-
if (requestOrigin.endsWith("/")) {
555-
requestOrigin = requestOrigin.substring(0, requestOrigin.length() - 1);
556-
}
561+
requestOrigin = trimTrailingSlash(requestOrigin);
557562
if (!ObjectUtils.isEmpty(this.allowedOrigins)) {
558563
if (this.allowedOrigins.contains(ALL)) {
559564
validateAllowCredentials();

spring-web/src/test/java/org/springframework/web/cors/CorsConfigurationTests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,17 +282,25 @@ public void combine() {
282282

283283
@Test
284284
public void checkOriginAllowed() {
285+
// "*" matches
285286
CorsConfiguration config = new CorsConfiguration();
286287
config.addAllowedOrigin("*");
287288
assertThat(config.checkOrigin("https://domain.com")).isEqualTo("*");
288289

290+
// "*" does not match together with allowCredentials
289291
config.setAllowCredentials(true);
290292
assertThatIllegalArgumentException().isThrownBy(() -> config.checkOrigin("https://domain.com"));
291293

294+
// specific origin matches Origin header with or without trailing "/"
292295
config.setAllowedOrigins(Collections.singletonList("https://domain.com"));
293296
assertThat(config.checkOrigin("https://domain.com")).isEqualTo("https://domain.com");
294297
assertThat(config.checkOrigin("https://domain.com/")).isEqualTo("https://domain.com");
295298

299+
// specific origin with trailing "/" matches Origin header with or without trailing "/"
300+
config.setAllowedOrigins(Collections.singletonList("https://domain.com/"));
301+
assertThat(config.checkOrigin("https://domain.com")).isEqualTo("https://domain.com");
302+
assertThat(config.checkOrigin("https://domain.com/")).isEqualTo("https://domain.com");
303+
296304
config.setAllowCredentials(false);
297305
assertThat(config.checkOrigin("https://domain.com")).isEqualTo("https://domain.com");
298306
}

0 commit comments

Comments
 (0)