Quellcode durchsuchen

SEC-1039: Converted HttpBeanDefinitionParser to use new context persistence filter instead of HttpSessionContextIntegrationFilter

Luke Taylor vor 17 Jahren
Ursprung
Commit
e864dfa796

+ 1 - 1
core/src/main/java/org/springframework/security/config/BeanIds.java

@@ -42,7 +42,7 @@ public abstract class BeanIds {
     public static final String OPEN_ID_PROVIDER = "_openIDAuthenticationProvider";
     public static final String MAIN_ENTRY_POINT = "_mainEntryPoint";
     public static final String FILTER_CHAIN_PROXY = "_filterChainProxy";
-    public static final String HTTP_SESSION_CONTEXT_INTEGRATION_FILTER = "_httpSessionContextIntegrationFilter";
+    public static final String SECURITY_CONTEXT_PERSISTENCE_FILTER = "_securityContextPersistenceFilter";
     public static final String LDAP_AUTHENTICATION_PROVIDER = "_ldapAuthenticationProvider";
     public static final String LOGOUT_FILTER = "_logoutFilter";
     public static final String EXCEPTION_TRANSLATION_FILTER = "_exceptionTranslationFilter";

+ 17 - 13
core/src/main/java/org/springframework/security/config/HttpSecurityBeanDefinitionParser.java

@@ -19,7 +19,8 @@ import org.springframework.beans.factory.xml.ParserContext;
 import org.springframework.security.ConfigAttribute;
 import org.springframework.security.ConfigAttributeEditor;
 import org.springframework.security.SecurityConfig;
-import org.springframework.security.context.HttpSessionContextIntegrationFilter;
+import org.springframework.security.context.HttpSessionSecurityContextRepository;
+import org.springframework.security.context.SecurityContextPersistenceFilter;
 import org.springframework.security.intercept.web.DefaultFilterInvocationDefinitionSource;
 import org.springframework.security.intercept.web.FilterSecurityInterceptor;
 import org.springframework.security.intercept.web.RequestKey;
@@ -121,7 +122,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
         parseInterceptUrlsForChannelSecurityAndFilterChain(interceptUrlElts, filterChainMap, channelRequestMap,
                 convertPathsToLowerCase, parserContext);
 
-        boolean allowSessionCreation = registerHttpSessionIntegrationFilter(element, parserContext);
+        boolean allowSessionCreation = registerSecurityContextPersistenceFilter(element, parserContext);
 
         registerServletApiFilter(element, parserContext);
 
@@ -219,26 +220,29 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
         pc.getRegistry().registerAlias(BeanIds.FILTER_CHAIN_PROXY, BeanIds.SPRING_SECURITY_FILTER_CHAIN);
     }
 
-    private boolean registerHttpSessionIntegrationFilter(Element element, ParserContext pc) {
-        RootBeanDefinition httpScif = new RootBeanDefinition(HttpSessionContextIntegrationFilter.class);
+    private boolean registerSecurityContextPersistenceFilter(Element element, ParserContext pc) {
+        BeanDefinitionBuilder scpf = BeanDefinitionBuilder.rootBeanDefinition(SecurityContextPersistenceFilter.class);
+        BeanDefinitionBuilder contextRepo = BeanDefinitionBuilder.rootBeanDefinition(HttpSessionSecurityContextRepository.class);
         boolean sessionCreationAllowed = true;
 
         String createSession = element.getAttribute(ATT_CREATE_SESSION);
         if (OPT_CREATE_SESSION_ALWAYS.equals(createSession)) {
-            httpScif.getPropertyValues().addPropertyValue("allowSessionCreation", Boolean.TRUE);
-            httpScif.getPropertyValues().addPropertyValue("forceEagerSessionCreation", Boolean.TRUE);
+            contextRepo.addPropertyValue("allowSessionCreation", Boolean.TRUE);
+            scpf.addPropertyValue("forceEagerSessionCreation", Boolean.TRUE);
         } else if (OPT_CREATE_SESSION_NEVER.equals(createSession)) {
-            httpScif.getPropertyValues().addPropertyValue("allowSessionCreation", Boolean.FALSE);
-            httpScif.getPropertyValues().addPropertyValue("forceEagerSessionCreation", Boolean.FALSE);
+            contextRepo.addPropertyValue("allowSessionCreation", Boolean.FALSE);
+            scpf.addPropertyValue("forceEagerSessionCreation", Boolean.FALSE);
             sessionCreationAllowed = false;
         } else {
             createSession = DEF_CREATE_SESSION_IF_REQUIRED;
-            httpScif.getPropertyValues().addPropertyValue("allowSessionCreation", Boolean.TRUE);
-            httpScif.getPropertyValues().addPropertyValue("forceEagerSessionCreation", Boolean.FALSE);
+            contextRepo.addPropertyValue("allowSessionCreation", Boolean.TRUE);
+            scpf.addPropertyValue("forceEagerSessionCreation", Boolean.FALSE);
         }
 
-        pc.getRegistry().registerBeanDefinition(BeanIds.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER, httpScif);
-        ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER));
+        scpf.addPropertyValue("securityContextRepository", contextRepo.getBeanDefinition());
+
+        pc.getRegistry().registerBeanDefinition(BeanIds.SECURITY_CONTEXT_PERSISTENCE_FILTER, scpf.getBeanDefinition());
+        ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.SECURITY_CONTEXT_PERSISTENCE_FILTER));
 
         return sessionCreationAllowed;
     }
@@ -265,7 +269,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
 
         new ConcurrentSessionsBeanDefinitionParser().parse(sessionControlElt, parserContext);
         logger.info("Concurrent session filter in use, setting 'forceEagerSessionCreation' to true");
-        BeanDefinition sessionIntegrationFilter = parserContext.getRegistry().getBeanDefinition(BeanIds.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER);
+        BeanDefinition sessionIntegrationFilter = parserContext.getRegistry().getBeanDefinition(BeanIds.SECURITY_CONTEXT_PERSISTENCE_FILTER);
         sessionIntegrationFilter.getPropertyValues().addPropertyValue("forceEagerSessionCreation", Boolean.TRUE);
         return true;
     }

+ 3 - 3
core/src/main/java/org/springframework/security/context/HttpSessionSecurityContextRepository.java

@@ -201,7 +201,7 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
     }
 
     @SuppressWarnings("unchecked")
-    void setSecurityContextClass(Class contextClass) {
+    public void setSecurityContextClass(Class contextClass) {
         if (contextClass == null || (!SecurityContext.class.isAssignableFrom(contextClass))) {
             throw new IllegalArgumentException("securityContextClass must implement SecurityContext "
                     + "(typically use org.springframework.security.context.SecurityContextImpl; existing class is "
@@ -212,11 +212,11 @@ public class HttpSessionSecurityContextRepository implements SecurityContextRepo
         contextObject = generateNewContext();
     }
 
-    void setCloneFromHttpSession(boolean cloneFromHttpSession) {
+    public void setCloneFromHttpSession(boolean cloneFromHttpSession) {
         this.cloneFromHttpSession = cloneFromHttpSession;
     }
 
-    void setAllowSessionCreation(boolean allowSessionCreation) {
+    public void setAllowSessionCreation(boolean allowSessionCreation) {
         this.allowSessionCreation = allowSessionCreation;
     }
 

+ 1 - 1
core/src/main/java/org/springframework/security/context/SecurityContextPersistenceFilter.java

@@ -85,7 +85,7 @@ public class SecurityContextPersistenceFilter extends SpringSecurityFilter {
         this.repo = repo;
     }
 
-    void setForceEagerSessionCreation(boolean forceEagerSessionCreation) {
+    public void setForceEagerSessionCreation(boolean forceEagerSessionCreation) {
         this.forceEagerSessionCreation = forceEagerSessionCreation;
     }
 

+ 26 - 26
core/src/test/java/org/springframework/security/config/HttpSecurityBeanDefinitionParserTests.java

@@ -1,17 +1,14 @@
 package org.springframework.security.config;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
 import static org.springframework.security.config.ConfigTestUtils.AUTH_PROVIDER_XML;
 
 import java.lang.reflect.Method;
 import java.util.Iterator;
 import java.util.List;
 
+import javax.servlet.Filter;
+
 import org.junit.After;
 import org.junit.Test;
 import org.springframework.beans.factory.BeanCreationException;
@@ -27,7 +24,7 @@ import org.springframework.security.SecurityConfig;
 import org.springframework.security.concurrent.ConcurrentLoginException;
 import org.springframework.security.concurrent.ConcurrentSessionControllerImpl;
 import org.springframework.security.concurrent.ConcurrentSessionFilter;
-import org.springframework.security.context.HttpSessionContextIntegrationFilter;
+import org.springframework.security.context.SecurityContextPersistenceFilter;
 import org.springframework.security.intercept.web.FilterInvocation;
 import org.springframework.security.intercept.web.FilterInvocationDefinitionSource;
 import org.springframework.security.intercept.web.FilterSecurityInterceptor;
@@ -80,7 +77,7 @@ public class HttpSecurityBeanDefinitionParserTests {
     public void httpAutoConfigSetsUpCorrectFilterList() throws Exception {
         setContext("<http auto-config='true' />" + AUTH_PROVIDER_XML);
 
-        List filterList = getFilters("/anyurl");
+        List<Filter> filterList = getFilters("/anyurl");
 
         checkAutoConfigFilters(filterList);
 
@@ -93,12 +90,12 @@ public class HttpSecurityBeanDefinitionParserTests {
         setContext("<http auto-config='true' /><http auto-config='true' />" + AUTH_PROVIDER_XML);
     }
 
-    private void checkAutoConfigFilters(List filterList) throws Exception {
+    private void checkAutoConfigFilters(List<Filter> filterList) throws Exception {
         assertEquals("Expected 11 filters in chain", 11, filterList.size());
 
-        Iterator filters = filterList.iterator();
+        Iterator<Filter> filters = filterList.iterator();
 
-        assertTrue(filters.next() instanceof HttpSessionContextIntegrationFilter);
+        assertTrue(filters.next() instanceof SecurityContextPersistenceFilter);
         assertTrue(filters.next() instanceof LogoutFilter);
         Object authProcFilter = filters.next();
         assertTrue(authProcFilter instanceof AuthenticationProcessingFilter);
@@ -127,7 +124,7 @@ public class HttpSecurityBeanDefinitionParserTests {
                 "        <intercept-url pattern='/unprotected' filters='none' />" +
                 "    </http>" + AUTH_PROVIDER_XML);
 
-        List filters = getFilters("/unprotected");
+        List<Filter> filters = getFilters("/unprotected");
 
         assertTrue(filters.size() == 0);
     }
@@ -140,7 +137,7 @@ public class HttpSecurityBeanDefinitionParserTests {
                 "    </http>" + AUTH_PROVIDER_XML);
         assertEquals(0, getFilters("/imlowercase").size());
         // This will be matched by the default pattern ".*"
-        List allFilters = getFilters("/ImCaughtByTheUniversalMatchPattern");
+        List<Filter> allFilters = getFilters("/ImCaughtByTheUniversalMatchPattern");
         checkAutoConfigFilters(allFilters);
         assertEquals(false, FieldUtils.getFieldValue(appContext.getBean("_filterChainProxy"), "stripQueryStringFromUrls"));
         assertEquals(false, FieldUtils.getFieldValue(allFilters.get(10), "objectDefinitionSource.stripQueryStringFromUrls"));
@@ -254,7 +251,7 @@ public class HttpSecurityBeanDefinitionParserTests {
     @Test
     public void oncePerRequestAttributeIsSupported() throws Exception {
         setContext("<http once-per-request='false'><http-basic /></http>" + AUTH_PROVIDER_XML);
-        List filters = getFilters("/someurl");
+        List<Filter> filters = getFilters("/someurl");
 
         FilterSecurityInterceptor fsi = (FilterSecurityInterceptor) filters.get(filters.size() - 1);
 
@@ -264,7 +261,7 @@ public class HttpSecurityBeanDefinitionParserTests {
     @Test
     public void accessDeniedPageAttributeIsSupported() throws Exception {
         setContext("<http access-denied-page='/access-denied'><http-basic /></http>" + AUTH_PROVIDER_XML);
-        List filters = getFilters("/someurl");
+        List<Filter> filters = getFilters("/someurl");
 
         ExceptionTranslationFilter etf = (ExceptionTranslationFilter) filters.get(filters.size() - 3);
 
@@ -282,7 +279,7 @@ public class HttpSecurityBeanDefinitionParserTests {
                 "    <http auto-config='true'>" +
                 "        <intercept-url pattern='/**' requires-channel='https' />" +
                 "    </http>" + AUTH_PROVIDER_XML);
-        List filters = getFilters("/someurl");
+        List<Filter> filters = getFilters("/someurl");
 
         assertEquals("Expected 12 filters in chain", 12, filters.size());
 
@@ -349,7 +346,7 @@ public class HttpSecurityBeanDefinitionParserTests {
                 "<b:bean id='userFilter3' class='org.springframework.security.util.MockFilter'/>" +
                 "<b:bean id='userFilter4' class='org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter'/>"
                 );
-        List filters = getFilters("/someurl");
+        List<Filter> filters = getFilters("/someurl");
 
         assertEquals(14, filters.size());
         assertTrue(filters.get(0) instanceof MockFilter);
@@ -442,7 +439,7 @@ public class HttpSecurityBeanDefinitionParserTests {
                 "<http auto-config='true'>" +
                 "    <x509 />" +
                 "</http>"  + AUTH_PROVIDER_XML);
-        List filters = getFilters("/someurl");
+        List<Filter> filters = getFilters("/someurl");
 
         assertTrue(filters.get(2) instanceof X509PreAuthenticatedProcessingFilter);
     }
@@ -453,7 +450,7 @@ public class HttpSecurityBeanDefinitionParserTests {
                 "<http auto-config='true'>" +
                 "    <concurrent-session-control session-registry-alias='seshRegistry' expired-url='/expired'/>" +
                 "</http>" + AUTH_PROVIDER_XML);
-        List filters = getFilters("/someurl");
+        List<Filter> filters = getFilters("/someurl");
 
         assertTrue(filters.get(0) instanceof ConcurrentSessionFilter);
         assertNotNull(appContext.getBean("seshRegistry"));
@@ -568,7 +565,7 @@ public class HttpSecurityBeanDefinitionParserTests {
     public void disablingSessionProtectionRemovesFilter() throws Exception {
         setContext(
                 "<http auto-config='true' session-fixation-protection='none'/>" + AUTH_PROVIDER_XML);
-        List filters = getFilters("/someurl");
+        List<Filter> filters = getFilters("/someurl");
 
         assertFalse(filters.get(1) instanceof SessionFixationProtectionFilter);
     }
@@ -638,15 +635,18 @@ public class HttpSecurityBeanDefinitionParserTests {
     @Test
     public void settingCreateSessionToAlwaysSetsFilterPropertiesCorrectly() throws Exception {
         setContext("<http auto-config='true' create-session='always'/>" + AUTH_PROVIDER_XML);
-        assertEquals(Boolean.TRUE, FieldUtils.getFieldValue(appContext.getBean(BeanIds.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER), "forceEagerSessionCreation"));
-        assertEquals(Boolean.TRUE, FieldUtils.getFieldValue(appContext.getBean(BeanIds.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER), "allowSessionCreation"));
+        Object filter = appContext.getBean(BeanIds.SECURITY_CONTEXT_PERSISTENCE_FILTER);
+
+        assertEquals(Boolean.TRUE, FieldUtils.getFieldValue(filter, "forceEagerSessionCreation"));
+        assertEquals(Boolean.TRUE, FieldUtils.getFieldValue(filter, "repo.allowSessionCreation"));
     }
 
     @Test
     public void settingCreateSessionToNeverSetsFilterPropertiesCorrectly() throws Exception {
         setContext("<http auto-config='true' create-session='never'/>" + AUTH_PROVIDER_XML);
-        assertEquals(Boolean.FALSE, FieldUtils.getFieldValue(appContext.getBean(BeanIds.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER), "forceEagerSessionCreation"));
-        assertEquals(Boolean.FALSE, FieldUtils.getFieldValue(appContext.getBean(BeanIds.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER), "allowSessionCreation"));
+        Object filter = appContext.getBean(BeanIds.SECURITY_CONTEXT_PERSISTENCE_FILTER);
+        assertEquals(Boolean.FALSE, FieldUtils.getFieldValue(filter, "forceEagerSessionCreation"));
+        assertEquals(Boolean.FALSE, FieldUtils.getFieldValue(filter, "repo.allowSessionCreation"));
     }
 
     /* SEC-934 */
@@ -669,11 +669,11 @@ public class HttpSecurityBeanDefinitionParserTests {
         appContext = new InMemoryXmlApplicationContext(context);
     }
 
-    private List getFilters(String url) throws Exception {
+    private List<Filter> getFilters(String url) throws Exception {
         FilterChainProxy fcp = (FilterChainProxy) appContext.getBean(BeanIds.FILTER_CHAIN_PROXY);
         Method getFilters = fcp.getClass().getDeclaredMethod("getFilters", String.class);
         getFilters.setAccessible(true);
-        return (List) ReflectionUtils.invokeMethod(getFilters, fcp, new Object[] {url});
+        return (List<Filter>) ReflectionUtils.invokeMethod(getFilters, fcp, new Object[] {url});
     }
 
     private FilterInvocation createFilterinvocation(String path, String method) {