Преглед на файлове

SEC-2215: ServletApiConfigurer populates properties on SecurityContextHolderAwareRequestFilter

Previously ServletApiConfigurer left the following properties null:
authenticationManager, logoutHandlers, and authenticationEntryPoint
Rob Winch преди 12 години
родител
ревизия
0f281f9575

+ 1 - 1
config/src/main/java/org/springframework/security/config/annotation/web/configurers/ExceptionHandlingConfigurer.java

@@ -132,7 +132,7 @@ public final class ExceptionHandlingConfigurer<H extends HttpSecurityBuilder<H>>
      * @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);

+ 9 - 0
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<H extends HttpSecurityBuilder<H>> extends Ab
         return logoutSuccessUrl;
     }
 
+    /**
+     * Gets the {@link LogoutHandler} instances that will be used.
+     * @return the {@link LogoutHandler} instances. Cannot be null.
+     */
+    List<LogoutHandler> getLogoutHandlers() {
+        return logoutHandlers;
+    }
+
     /**
      * Creates the {@link LogoutFilter} using the {@link LogoutHandler}
      * instances, the {@link #logoutSuccessHandler(LogoutSuccessHandler)} and

+ 14 - 3
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<H extends HttpSecurityBuilder<H>> extend
     }
 
     @Override
-    public void configure(H builder)
-            throws Exception {
+    @SuppressWarnings("unchecked")
+    public void configure(H http) throws Exception {
+        securityContextRequestFilter.setAuthenticationManager(http.getAuthenticationManager());
+        ExceptionHandlingConfigurer<H> exceptionConf = http.getConfigurer(ExceptionHandlingConfigurer.class);
+        AuthenticationEntryPoint authenticationEntryPoint = exceptionConf == null ? null : exceptionConf.getEntryPoint(http);
+        securityContextRequestFilter.setAuthenticationEntryPoint(authenticationEntryPoint);
+        LogoutConfigurer<H> logoutConf = http.getConfigurer(LogoutConfigurer.class);
+        List<LogoutHandler> logoutHandlers = logoutConf == null ? null : logoutConf.getLogoutHandlers();
+        securityContextRequestFilter.setLogoutHandlers(logoutHandlers);
         securityContextRequestFilter = postProcess(securityContextRequestFilter);
-        builder.addFilter(securityContextRequestFilter);
+        http.addFilter(securityContextRequestFilter);
     }
 }

+ 69 - 2
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")
+        }
+    }
 }