diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RequestCacheConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RequestCacheConfigurer.java index 662a01ac81..4002a3b9f4 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RequestCacheConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/RequestCacheConfigurer.java @@ -185,7 +185,10 @@ public final class RequestCacheConfigurer> "/apple-touch-icon*.png", // Chromium browsers fetch the web app manifest in the background to // evaluate PWA installability - "/manifest.json", "/manifest.webmanifest" }; + "/manifest.json", "/manifest.webmanifest", + // Legacy IE11/Edge fetch browserconfig.xml in the background to + // configure pinned-site tiles + "/browserconfig.xml" }; private RequestMatcher getIgnoredBackgroundRequestMatcher() { List matchers = new ArrayList<>(); diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RequestCacheConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RequestCacheConfigurerTests.java index 6ecffb7c25..48c7304ea3 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RequestCacheConfigurerTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/RequestCacheConfigurerTests.java @@ -186,6 +186,20 @@ public class RequestCacheConfigurerTests { this.mvc.perform(formLogin(session)).andExpect(redirectedUrl("/")); } + @Test + public void getWhenBookmarkedUrlIsBrowserConfigXmlThenPostAuthenticationRedirectsToRoot() throws Exception { + this.spring.register(RequestCacheDefaultsConfig.class, DefaultSecurityConfig.class).autowire(); + // @formatter:off + MockHttpSession session = (MockHttpSession) this.mvc.perform(get("/browserconfig.xml")) + .andExpect(redirectedUrl("/login")) + .andReturn() + .getRequest() + .getSession(); + // @formatter:on + // ignores browserconfig.xml + this.mvc.perform(formLogin(session)).andExpect(redirectedUrl("/")); + } + // SEC-2321 @Test public void getWhenBookmarkedRequestIsApplicationJsonThenPostAuthenticationRedirectsToRoot() throws Exception { diff --git a/web/src/main/java/org/springframework/security/web/server/savedrequest/CookieServerRequestCache.java b/web/src/main/java/org/springframework/security/web/server/savedrequest/CookieServerRequestCache.java index 25d9dba0fd..4361bf7dc3 100644 --- a/web/src/main/java/org/springframework/security/web/server/savedrequest/CookieServerRequestCache.java +++ b/web/src/main/java/org/springframework/security/web/server/savedrequest/CookieServerRequestCache.java @@ -171,7 +171,10 @@ public class CookieServerRequestCache implements ServerRequestCache { "/apple-touch-icon*.png", // Chromium browsers fetch the web app manifest in the background to // evaluate PWA installability - "/manifest.json", "/manifest.webmanifest" }; + "/manifest.json", "/manifest.webmanifest", + // Legacy IE11/Edge fetch browserconfig.xml in the background to + // configure pinned-site tiles + "/browserconfig.xml" }; private static ServerWebExchangeMatcher createDefaultRequestMatcher() { ServerWebExchangeMatcher get = ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, "/**"); diff --git a/web/src/main/java/org/springframework/security/web/server/savedrequest/WebSessionServerRequestCache.java b/web/src/main/java/org/springframework/security/web/server/savedrequest/WebSessionServerRequestCache.java index 279c6d865d..b3f72559ae 100644 --- a/web/src/main/java/org/springframework/security/web/server/savedrequest/WebSessionServerRequestCache.java +++ b/web/src/main/java/org/springframework/security/web/server/savedrequest/WebSessionServerRequestCache.java @@ -171,7 +171,10 @@ public class WebSessionServerRequestCache implements ServerRequestCache { "/apple-touch-icon*.png", // Chromium browsers fetch the web app manifest in the background to // evaluate PWA installability - "/manifest.json", "/manifest.webmanifest" }; + "/manifest.json", "/manifest.webmanifest", + // Legacy IE11/Edge fetch browserconfig.xml in the background to + // configure pinned-site tiles + "/browserconfig.xml" }; private static ServerWebExchangeMatcher createDefaultRequestMatcher() { ServerWebExchangeMatcher get = ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, "/**"); diff --git a/web/src/test/java/org/springframework/security/web/server/savedrequest/CookieServerRequestCacheTests.java b/web/src/test/java/org/springframework/security/web/server/savedrequest/CookieServerRequestCacheTests.java index 75624d58c7..efe80eb252 100644 --- a/web/src/test/java/org/springframework/security/web/server/savedrequest/CookieServerRequestCacheTests.java +++ b/web/src/test/java/org/springframework/security/web/server/savedrequest/CookieServerRequestCacheTests.java @@ -122,6 +122,15 @@ public class CookieServerRequestCacheTests { assertThat(cookies).isEmpty(); } + @Test + public void saveRequestWhenGetRequestBrowserConfigXmlThenNoCookie() { + MockServerWebExchange exchange = MockServerWebExchange + .from(MockServerHttpRequest.get("/browserconfig.xml").accept(MediaType.TEXT_HTML)); + this.cache.saveRequest(exchange).block(); + MultiValueMap cookies = exchange.getResponse().getCookies(); + assertThat(cookies).isEmpty(); + } + @Test public void saveRequestWhenPostRequestThenNoCookie() { MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.post("/secured/")); diff --git a/web/src/test/java/org/springframework/security/web/server/savedrequest/WebSessionServerRequestCacheTests.java b/web/src/test/java/org/springframework/security/web/server/savedrequest/WebSessionServerRequestCacheTests.java index 4b68546025..7acb99943a 100644 --- a/web/src/test/java/org/springframework/security/web/server/savedrequest/WebSessionServerRequestCacheTests.java +++ b/web/src/test/java/org/springframework/security/web/server/savedrequest/WebSessionServerRequestCacheTests.java @@ -113,6 +113,15 @@ public class WebSessionServerRequestCacheTests { assertThat(saved).isNull(); } + @Test + public void saveRequestGetRequestWhenBrowserConfigXmlThenNotFound() { + MockServerWebExchange exchange = MockServerWebExchange + .from(MockServerHttpRequest.get("/browserconfig.xml").accept(MediaType.TEXT_HTML)); + this.cache.saveRequest(exchange).block(); + URI saved = this.cache.getRedirectUri(exchange).block(); + assertThat(saved).isNull(); + } + @Test public void saveRequestGetRequestWhenPostThenNotFound() { MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.post("/secured/"));