diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/ExceptionHandlingConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/ExceptionHandlingConfigurer.java index 128327f0d4..4bcab960d5 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/ExceptionHandlingConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/ExceptionHandlingConfigurer.java @@ -132,7 +132,7 @@ public final class ExceptionHandlingConfigurer> * @param http the {@link HttpSecurity} used to look up shared {@link AuthenticationEntryPoint} * @return the {@link AuthenticationEntryPoint} to use */ - private AuthenticationEntryPoint getEntryPoint(H http) { + AuthenticationEntryPoint getEntryPoint(H http) { AuthenticationEntryPoint entryPoint = this.authenticationEntryPoint; if(entryPoint == null) { AuthenticationEntryPoint sharedEntryPoint = http.getSharedObject(AuthenticationEntryPoint.class); diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.java index 238b8a7997..4f36b8f102 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/LogoutConfigurer.java @@ -16,6 +16,7 @@ package org.springframework.security.config.annotation.web.configurers; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import javax.servlet.http.HttpSession; @@ -224,6 +225,14 @@ public final class LogoutConfigurer> extends Ab return logoutSuccessUrl; } + /** + * Gets the {@link LogoutHandler} instances that will be used. + * @return the {@link LogoutHandler} instances. Cannot be null. + */ + List getLogoutHandlers() { + return logoutHandlers; + } + /** * Creates the {@link LogoutFilter} using the {@link LogoutHandler} * instances, the {@link #logoutSuccessHandler(LogoutSuccessHandler)} and diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/ServletApiConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/ServletApiConfigurer.java index 3554662252..baa5499aad 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/ServletApiConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/ServletApiConfigurer.java @@ -15,12 +15,16 @@ */ package org.springframework.security.config.annotation.web.configurers; +import java.util.List; + import javax.servlet.http.HttpServletRequest; import org.springframework.security.config.annotation.web.HttpSecurityBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.authentication.logout.LogoutHandler; import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter; /** @@ -67,9 +71,16 @@ public final class ServletApiConfigurer> extend } @Override - public void configure(H builder) - throws Exception { + @SuppressWarnings("unchecked") + public void configure(H http) throws Exception { + securityContextRequestFilter.setAuthenticationManager(http.getAuthenticationManager()); + ExceptionHandlingConfigurer exceptionConf = http.getConfigurer(ExceptionHandlingConfigurer.class); + AuthenticationEntryPoint authenticationEntryPoint = exceptionConf == null ? null : exceptionConf.getEntryPoint(http); + securityContextRequestFilter.setAuthenticationEntryPoint(authenticationEntryPoint); + LogoutConfigurer logoutConf = http.getConfigurer(LogoutConfigurer.class); + List logoutHandlers = logoutConf == null ? null : logoutConf.getLogoutHandlers(); + securityContextRequestFilter.setLogoutHandlers(logoutHandlers); securityContextRequestFilter = postProcess(securityContextRequestFilter); - builder.addFilter(securityContextRequestFilter); + http.addFilter(securityContextRequestFilter); } } \ No newline at end of file diff --git a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/ServletApiConfigurerTests.groovy b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/ServletApiConfigurerTests.groovy index 5e35acdf59..3a795a3507 100644 --- a/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/ServletApiConfigurerTests.groovy +++ b/config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/ServletApiConfigurerTests.groovy @@ -15,10 +15,17 @@ */ package org.springframework.security.config.annotation.web.configurers +import groovy.transform.CompileStatic + +import org.springframework.context.annotation.Configuration import org.springframework.security.config.annotation.AnyObjectPostProcessor import org.springframework.security.config.annotation.BaseSpringSpec -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder +import org.springframework.security.config.annotation.web.builders.HttpSecurity +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter +import org.springframework.security.web.AuthenticationEntryPoint +import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter /** @@ -40,4 +47,64 @@ class ServletApiConfigurerTests extends BaseSpringSpec { then: "SecurityContextHolderAwareRequestFilter is registered with LifecycleManager" 1 * opp.postProcess(_ as SecurityContextHolderAwareRequestFilter) >> {SecurityContextHolderAwareRequestFilter o -> o} } + + def "SecurityContextHolderAwareRequestFilter properties set"() { + when: + loadConfig(ServletApiConfig) + SecurityContextHolderAwareRequestFilter filter = findFilter(SecurityContextHolderAwareRequestFilter) + then: "SEC-2215: authenticationManager != null" + filter.authenticationManager != null + and: "authenticationEntryPoint != null" + filter.authenticationEntryPoint != null + and: "requestFactory != null" + filter.requestFactory != null + and: "logoutHandlers populated" + filter.logoutHandlers.collect { it.class } == [SecurityContextLogoutHandler] + } + + @CompileStatic + @EnableWebSecurity + @Configuration + static class ServletApiConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void registerAuthentication(AuthenticationManagerBuilder auth) + throws Exception { + auth + .inMemoryAuthentication() + .withUser("user").password("password").roles("USER") + } + } + + def "SecurityContextHolderAwareRequestFilter.authenticationEntryPoint = customEntryPoint"() { + setup: + CustomEntryPointConfig.ENTRYPOINT = Mock(AuthenticationEntryPoint) + when: "load config with customEntryPoint" + loadConfig(CustomEntryPointConfig) + then: "SecurityContextHolderAwareRequestFilter.authenticationEntryPoint == customEntryPoint" + findFilter(SecurityContextHolderAwareRequestFilter).authenticationEntryPoint == CustomEntryPointConfig.ENTRYPOINT + } + + @EnableWebSecurity + @Configuration + static class CustomEntryPointConfig extends WebSecurityConfigurerAdapter { + static AuthenticationEntryPoint ENTRYPOINT + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .exceptionHandling() + .authenticationEntryPoint(ENTRYPOINT) + .and() + .formLogin() + } + + @Override + protected void registerAuthentication(AuthenticationManagerBuilder auth) + throws Exception { + auth + .inMemoryAuthentication() + .withUser("user").password("password").roles("USER") + } + } }