diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterOrderRegistration.java b/config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterOrderRegistration.java index 7ba8cb1386e..6f297cdb231 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterOrderRegistration.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterOrderRegistration.java @@ -38,6 +38,7 @@ import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; import org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter; import org.springframework.security.web.authentication.ui.DefaultOneTimeTokenSubmitPageGeneratingFilter; +import org.springframework.security.web.authentication.ui.DefaultResourcesFilter; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.authentication.www.DigestAuthenticationFilter; import org.springframework.security.web.context.SecurityContextHolderFilter; @@ -101,6 +102,7 @@ final class FilterOrderRegistration { order.next()); put(UsernamePasswordAuthenticationFilter.class, order.next()); order.next(); // gh-8105 + put(DefaultResourcesFilter.class, order.next()); put(DefaultLoginPageGeneratingFilter.class, order.next()); put(DefaultLogoutPageGeneratingFilter.class, order.next()); put(DefaultOneTimeTokenSubmitPageGeneratingFilter.class, order.next()); diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/DefaultLoginPageConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/DefaultLoginPageConfigurer.java index 4e955e36882..af024ee2d83 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/DefaultLoginPageConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/DefaultLoginPageConfigurer.java @@ -26,6 +26,7 @@ import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; import org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter; +import org.springframework.security.web.authentication.ui.DefaultResourcesFilter; import org.springframework.security.web.csrf.CsrfToken; /** @@ -98,6 +99,7 @@ public void configure(H http) { if (this.loginPageGeneratingFilter.isEnabled() && authenticationEntryPoint == null) { this.loginPageGeneratingFilter = postProcess(this.loginPageGeneratingFilter); http.addFilter(this.loginPageGeneratingFilter); + http.addFilter(DefaultResourcesFilter.css()); LogoutConfigurer logoutConfigurer = http.getConfigurer(LogoutConfigurer.class); if (logoutConfigurer != null) { http.addFilter(this.logoutPageGeneratingFilter); diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/ott/OneTimeTokenLoginConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/ott/OneTimeTokenLoginConfigurer.java index 03b75e87eeb..a8ae662e604 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/ott/OneTimeTokenLoginConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/ott/OneTimeTokenLoginConfigurer.java @@ -46,6 +46,7 @@ import org.springframework.security.web.authentication.ott.OneTimeTokenAuthenticationConverter; import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; import org.springframework.security.web.authentication.ui.DefaultOneTimeTokenSubmitPageGeneratingFilter; +import org.springframework.security.web.authentication.ui.DefaultResourcesFilter; import org.springframework.security.web.context.HttpSessionSecurityContextRepository; import org.springframework.security.web.context.SecurityContextRepository; import org.springframework.security.web.csrf.CsrfToken; @@ -136,6 +137,7 @@ private void configureOttGenerateFilter(H http) { generateFilter.setGeneratedOneTimeTokenHandler(getGeneratedOneTimeTokenHandler(http)); generateFilter.setRequestMatcher(antMatcher(HttpMethod.POST, this.generateTokenUrl)); http.addFilter(postProcess(generateFilter)); + http.addFilter(DefaultResourcesFilter.css()); } private GeneratedOneTimeTokenHandler getGeneratedOneTimeTokenHandler(H http) { diff --git a/config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java b/config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java index 2a7f38e8a1e..e2bb5ebb7fe 100644 --- a/config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java +++ b/config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java @@ -194,6 +194,7 @@ import org.springframework.security.web.server.savedrequest.ServerRequestCacheWebFilter; import org.springframework.security.web.server.savedrequest.WebSessionServerRequestCache; import org.springframework.security.web.server.transport.HttpsRedirectWebFilter; +import org.springframework.security.web.server.ui.DefaultResourcesWebFilter; import org.springframework.security.web.server.ui.LoginPageGeneratingWebFilter; import org.springframework.security.web.server.ui.LogoutPageGeneratingWebFilter; import org.springframework.security.web.server.util.matcher.AndServerWebExchangeMatcher; @@ -2974,6 +2975,7 @@ protected void configure(ServerHttpSecurity http) { } if (loginPage != null) { http.addFilterAt(loginPage, SecurityWebFiltersOrder.LOGIN_PAGE_GENERATING); + http.addFilterBefore(DefaultResourcesWebFilter.css(), SecurityWebFiltersOrder.LOGIN_PAGE_GENERATING); if (http.logout != null) { http.addFilterAt(new LogoutPageGeneratingWebFilter(), SecurityWebFiltersOrder.LOGOUT_PAGE_GENERATING); diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/DefaultLoginPageConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/DefaultLoginPageConfigurerTests.java index d49ade6696d..7a689529453 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/DefaultLoginPageConfigurerTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/DefaultLoginPageConfigurerTests.java @@ -38,6 +38,7 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler; import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; +import org.springframework.security.web.authentication.ui.DefaultResourcesFilter; import org.springframework.security.web.csrf.CsrfToken; import org.springframework.security.web.csrf.DefaultCsrfToken; import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository; @@ -46,6 +47,7 @@ import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.containsString; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @@ -55,6 +57,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -67,143 +70,6 @@ @ExtendWith(SpringTestContextExtension.class) public class DefaultLoginPageConfigurerTests { - public static final String EXPECTED_HTML_HEAD = """ - - - - - - - - Please sign in - - - """; - public final SpringTestContext spring = new SpringTestContext(this); @Autowired @@ -224,9 +90,17 @@ public void loginPageThenDefaultLoginPageIsRendered() throws Exception { this.mvc.perform(get("/login").sessionAttr(csrfAttributeName, csrfToken)) .andExpect((result) -> { CsrfToken token = (CsrfToken) result.getRequest().getAttribute(CsrfToken.class.getName()); - assertThat(result.getResponse().getContentAsString()).isEqualTo( - EXPECTED_HTML_HEAD + - """ + assertThat(result.getResponse().getContentAsString()).isEqualTo(""" + + + + + + + + Please sign in + +