Browse Source

SEC-2913: Post Process default session fixation AuthenticationStrategy

Before the default session fixation AuthenticationStrategy used a
NullEventPublisher when using the Java Configuration. This was due to the
fact that it is not exposed as a Bean and is not post processed.

We now post process the default session fixation AuthenticationStrategy
which initializes the EventPublisher properly.
Rob Winch 10 năm trước cách đây
mục cha
commit
b0ad8173b0

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

@@ -88,7 +88,8 @@ import org.springframework.util.Assert;
  * @see ConcurrentSessionFilter
  */
 public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>> extends AbstractHttpConfigurer<SessionManagementConfigurer<H>,H> {
-    private SessionAuthenticationStrategy sessionFixationAuthenticationStrategy = createDefaultSessionFixationProtectionStrategy();
+    private final SessionAuthenticationStrategy DEFAULT_SESSION_FIXATION_STRATEGY = createDefaultSessionFixationProtectionStrategy();
+    private SessionAuthenticationStrategy sessionFixationAuthenticationStrategy = DEFAULT_SESSION_FIXATION_STRATEGY;
     private SessionAuthenticationStrategy sessionAuthenticationStrategy;
     private InvalidSessionStrategy invalidSessionStrategy;
     private List<SessionAuthenticationStrategy> sessionAuthenticationStrategies = new ArrayList<SessionAuthenticationStrategy>();
@@ -454,6 +455,9 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
             return sessionAuthenticationStrategy;
         }
         List<SessionAuthenticationStrategy> delegateStrategies = sessionAuthenticationStrategies;
+        if(DEFAULT_SESSION_FIXATION_STRATEGY == sessionFixationAuthenticationStrategy) {
+            sessionFixationAuthenticationStrategy = postProcess(sessionFixationAuthenticationStrategy);
+        }
         if(isConcurrentSessionControlEnabled()) {
             SessionRegistry sessionRegistry = getSessionRegistry(http);
             ConcurrentSessionControlAuthenticationStrategy concurrentSessionControlStrategy = new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry);

+ 42 - 9
config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceSessionManagementTests.groovy

@@ -15,19 +15,20 @@
  */
 package org.springframework.security.config.annotation.web.configurers
 
+import org.springframework.context.ApplicationListener
+import org.springframework.context.annotation.Bean
 import org.springframework.context.annotation.Configuration
+import org.springframework.mock.web.MockHttpSession
+import org.springframework.security.authentication.TestingAuthenticationToken
 import org.springframework.security.config.annotation.BaseSpringSpec
-import org.springframework.security.config.annotation.ObjectPostProcessor
-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.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.core.session.SessionRegistry
-import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
-import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
+import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy
+import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy
+import org.springframework.security.web.authentication.session.SessionFixationProtectionEvent
 import org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy
-import org.springframework.security.web.context.SecurityContextPersistenceFilter
-import org.springframework.security.web.context.SecurityContextRepository
 import org.springframework.security.web.session.ConcurrentSessionFilter
 import org.springframework.security.web.session.SessionManagementFilter
 
@@ -141,6 +142,29 @@ class NamespaceSessionManagementTests extends BaseSpringSpec {
         }
     }
 
+    def "SEC-2913: Default JavaConfig session fixation AuthenticationStrategy has NullEventPublisher"() {
+        setup:
+            loadConfig(SFPPostProcessedConfig)
+        when:
+            findSessionAuthenticationStrategy(SessionFixationProtectionStrategy).onSessionChange("id", new MockHttpSession(), new TestingAuthenticationToken("u","p","ROLE_USER"))
+        then:
+            context.getBean(MockEventListener).events
+    }
+
+    @EnableWebSecurity
+    static class SFPPostProcessedConfig extends WebSecurityConfigurerAdapter {
+        @Override
+        protected void configure(HttpSecurity http) throws Exception {
+            http
+                .sessionManagement()
+        }
+
+        @Bean
+        public MockEventListener eventListener() {
+            new MockEventListener()
+        }
+    }
+
     def "http/session-management@session-fixation-protection=newSession"() {
         when:
             loadConfig(SFPNewSessionSessionManagementConfig)
@@ -163,4 +187,13 @@ class NamespaceSessionManagementTests extends BaseSpringSpec {
                         .newSession()
         }
     }
+
+    static class MockEventListener implements ApplicationListener<SessionFixationProtectionEvent> {
+        List<SessionFixationProtectionEvent> events = []
+
+        public void onApplicationEvent(SessionFixationProtectionEvent event) {
+            events.add(event)
+        }
+
+    }
 }

+ 5 - 3
config/src/test/groovy/org/springframework/security/config/annotation/web/configurers/SessionManagementConfigurerTests.groovy

@@ -21,7 +21,7 @@ import org.springframework.context.annotation.Configuration
 import org.springframework.mock.web.MockFilterChain
 import org.springframework.mock.web.MockHttpServletRequest
 import org.springframework.mock.web.MockHttpServletResponse
-import org.springframework.security.authentication.AuthenticationTrustResolver;
+import org.springframework.security.authentication.AuthenticationTrustResolver
 import org.springframework.security.config.annotation.AnyObjectPostProcessor
 import org.springframework.security.config.annotation.BaseSpringSpec
 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
@@ -29,17 +29,17 @@ 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.config.http.SessionCreationPolicy
-import org.springframework.security.core.session.SessionDestroyedEvent
 import org.springframework.security.web.access.ExceptionTranslationFilter
 import org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy
 import org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy
 import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy
+import org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy
 import org.springframework.security.web.context.NullSecurityContextRepository
 import org.springframework.security.web.context.SecurityContextPersistenceFilter
 import org.springframework.security.web.context.SecurityContextRepository
 import org.springframework.security.web.savedrequest.RequestCache
 import org.springframework.security.web.session.ConcurrentSessionFilter
-import org.springframework.security.web.session.HttpSessionDestroyedEvent;
+import org.springframework.security.web.session.HttpSessionDestroyedEvent
 import org.springframework.security.web.session.SessionManagementFilter
 
 /**
@@ -232,6 +232,8 @@ class SessionManagementConfigurerTests extends BaseSpringSpec {
             1 * opp.postProcess(_ as CompositeSessionAuthenticationStrategy) >> {CompositeSessionAuthenticationStrategy o -> o}
         and: "RegisterSessionAuthenticationStrategy is registered with ObjectPostProcessor"
             1 * opp.postProcess(_ as RegisterSessionAuthenticationStrategy) >> {RegisterSessionAuthenticationStrategy o -> o}
+        and: "SessionFixationProtectionStrategy is registered with ObjectPostProcessor"
+            1 * opp.postProcess(_ as SessionFixationProtectionStrategy) >> {SessionFixationProtectionStrategy o -> o}
     }
 
     def "use sharedObject trustResolver"() {