diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java b/config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java index b8d607d254..7b1884b86b 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java @@ -1056,6 +1056,46 @@ public final class HttpSecurity extends return getOrApply(new RequestCacheConfigurer<>()); } + /** + * Allows configuring the Request Cache. For example, a protected page (/protected) + * may be requested prior to authentication. The application will redirect the user to + * a login page. After authentication, Spring Security will redirect the user to the + * originally requested protected page (/protected). This is automatically applied + * when using {@link WebSecurityConfigurerAdapter}. + * + *

Example Custom Configuration

+ * + * The following example demonstrates how to disable request caching. + * + *
+	 * @Configuration
+	 * @EnableWebSecurity
+	 * public class RequestCacheDisabledSecurityConfig extends WebSecurityConfigurerAdapter {
+	 *
+	 * 	@Override
+	 * 	protected void configure(HttpSecurity http) throws Exception {
+	 * 		http
+	 * 			.authorizeRequests()
+	 * 				.antMatchers("/**").hasRole("USER")
+	 * 				.and()
+	 * 			.requestCache(requestCache ->
+	 * 				requestCache.disable()
+	 * 			);
+	 * 	}
+	 * }
+	 * 
+ * + * @param requestCacheCustomizer the {@link Customizer} to provide more options for + * the {@link RequestCacheConfigurer} + * @return the {@link HttpSecurity} for further customizations + * @throws Exception + */ + public HttpSecurity requestCache(Customizer> requestCacheCustomizer) + throws Exception { + requestCacheCustomizer.customize(getOrApply(new RequestCacheConfigurer<>())); + return HttpSecurity.this; + } + /** * Allows configuring exception handling. This is automatically applied when using * {@link WebSecurityConfigurerAdapter}. 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 683a4951c2..c21aca1162 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -33,6 +33,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur import org.springframework.security.config.test.SpringTestRule; import org.springframework.security.core.userdetails.User; import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.savedrequest.NullRequestCache; import org.springframework.security.web.savedrequest.RequestCache; import org.springframework.security.web.savedrequest.RequestCacheAwareFilter; import org.springframework.test.web.servlet.MockMvc; @@ -42,6 +43,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +import static org.springframework.security.config.Customizer.withDefaults; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -271,6 +273,90 @@ public class RequestCacheConfigurerTests { } } + @Test + public void getWhenRequestCacheIsDisabledInLambdaThenExceptionTranslationFilterDoesNotStoreRequest() throws Exception { + this.spring.register(RequestCacheDisabledInLambdaConfig.class, DefaultSecurityConfig.class).autowire(); + + MockHttpSession session = (MockHttpSession) + this.mvc.perform(get("/bob")) + .andReturn().getRequest().getSession(); + + this.mvc.perform(formLogin(session)) + .andExpect(redirectedUrl("/")); + } + + @EnableWebSecurity + static class RequestCacheDisabledInLambdaConfig extends WebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http + .authorizeRequests() + .anyRequest().authenticated() + .and() + .formLogin(withDefaults()) + .requestCache(RequestCacheConfigurer::disable); + // @formatter:on + } + } + + @Test + public void getWhenRequestCacheInLambdaThenRedirectedToCachedPage() throws Exception { + this.spring.register(RequestCacheInLambdaConfig.class, DefaultSecurityConfig.class).autowire(); + + MockHttpSession session = (MockHttpSession) + this.mvc.perform(get("/bob")) + .andReturn().getRequest().getSession(); + + this.mvc.perform(formLogin(session)) + .andExpect(redirectedUrl("http://localhost/bob")); + } + + @EnableWebSecurity + static class RequestCacheInLambdaConfig extends WebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http + .authorizeRequests() + .anyRequest().authenticated() + .and() + .formLogin(withDefaults()) + .requestCache(withDefaults()); + // @formatter:on + } + } + + @Test + public void getWhenCustomRequestCacheInLambdaThenCustomRequestCacheUsed() throws Exception { + this.spring.register(CustomRequestCacheInLambdaConfig.class, DefaultSecurityConfig.class).autowire(); + + MockHttpSession session = (MockHttpSession) + this.mvc.perform(get("/bob")) + .andReturn().getRequest().getSession(); + + this.mvc.perform(formLogin(session)) + .andExpect(redirectedUrl("/")); + } + + @EnableWebSecurity + static class CustomRequestCacheInLambdaConfig extends WebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http + .authorizeRequests() + .anyRequest().authenticated() + .and() + .formLogin(withDefaults()) + .requestCache(requestCache -> + requestCache + .requestCache(new NullRequestCache()) + ); + // @formatter:on + } + } + @EnableWebSecurity static class DefaultSecurityConfig {