Don't cache WebSocket request

PR gh-16741

Signed-off-by: Kevin Yue <yuezk001@gmail.com>
This commit is contained in:
Kevin Yue 2025-03-16 23:06:22 +08:00 committed by Rob Winch
parent 2f53a2edb3
commit 7de4217469
2 changed files with 22 additions and 1 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -145,6 +145,9 @@ public final class RequestCacheConfigurer<H extends HttpSecurityBuilder<H>>
RequestMatcher notFavIcon = new NegatedRequestMatcher(getFaviconRequestMatcher());
RequestMatcher notXRequestedWith = new NegatedRequestMatcher(
new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest"));
RequestMatcher notWebSocket = new NegatedRequestMatcher(
new RequestHeaderRequestMatcher("Upgrade", "websocket"));
boolean isCsrfEnabled = http.getConfigurer(CsrfConfigurer.class) != null;
List<RequestMatcher> matchers = new ArrayList<>();
if (isCsrfEnabled) {
@ -156,6 +159,7 @@ public final class RequestCacheConfigurer<H extends HttpSecurityBuilder<H>>
matchers.add(notXRequestedWith);
matchers.add(notMatchingMediaType(http, MediaType.MULTIPART_FORM_DATA));
matchers.add(notMatchingMediaType(http, MediaType.TEXT_EVENT_STREAM));
matchers.add(notWebSocket);
return new AndRequestMatcher(matchers);
}

View File

@ -169,6 +169,23 @@ public class RequestCacheConfigurerTests {
this.mvc.perform(formLogin(session)).andExpect(redirectedUrl("/"));
}
@Test
public void getWhenBookmarkedRequestIsWebSocketThenPostAuthenticationRedirectsToRoot() throws Exception {
this.spring.register(RequestCacheDefaultsConfig.class, DefaultSecurityConfig.class).autowire();
MockHttpServletRequestBuilder request = get("/messages").header("Upgrade", "websocket");
// @formatter:off
MockHttpSession session = (MockHttpSession) this.mvc.perform(request)
.andExpect(redirectedUrl("http://localhost/login"))
.andReturn()
.getRequest()
.getSession();
// @formatter:on
// ignores websocket
// This is desirable since websocket requests are typically not invoked
// directly from the browser and we don't want the browser to replay them
this.mvc.perform(formLogin(session)).andExpect(redirectedUrl("/"));
}
@Test
public void getWhenBookmarkedRequestIsAllMediaTypeThenPostAuthenticationRemembers() throws Exception {
this.spring.register(RequestCacheDefaultsConfig.class, DefaultSecurityConfig.class).autowire();