| 
					
				 | 
			
			
				@@ -1,27 +1,39 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 package org.springframework.security.config; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import org.springframework.beans.factory.config.BeanDefinition; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import org.springframework.beans.factory.support.BeanDefinitionBuilder; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import org.springframework.beans.factory.support.BeanDefinitionRegistry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import org.springframework.beans.factory.support.RootBeanDefinition; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import org.springframework.beans.factory.xml.BeanDefinitionParser; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import org.springframework.beans.factory.xml.ParserContext; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.security.ConfigAttributeDefinition; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.security.ConfigAttributeEditor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.security.context.HttpSessionContextIntegrationFilter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.security.intercept.web.AbstractFilterInvocationDefinitionSource; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.security.intercept.web.FilterInvocationDefinitionMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.security.intercept.web.FilterSecurityInterceptor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.security.intercept.web.PathBasedFilterInvocationDefinitionMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.security.intercept.web.RegExpBasedFilterInvocationDefinitionMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.security.securechannel.ChannelDecisionManagerImpl; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.security.securechannel.ChannelProcessingFilter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.security.securechannel.InsecureChannelProcessor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.security.securechannel.SecureChannelProcessor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.security.ui.ExceptionTranslationFilter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.security.util.FilterChainProxy; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.security.util.RegexUrlPathMatcher; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.beans.factory.config.BeanDefinition; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.beans.factory.config.RuntimeBeanReference; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.beans.factory.support.BeanDefinitionBuilder; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.beans.factory.support.BeanDefinitionRegistry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.beans.factory.support.RootBeanDefinition; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.beans.factory.xml.BeanDefinitionParser; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.springframework.beans.factory.xml.ParserContext; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.util.Assert; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.util.StringUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.util.xml.DomUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.w3c.dom.Element; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import java.util.*; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.ArrayList; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.Collections; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.Iterator; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.LinkedHashMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.List; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.Map; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * Sets up HTTP security: filter stack and protected URLs. 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -38,6 +50,8 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public static final String DEFAULT_LOGOUT_FILTER_ID = "_logoutFilter"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public static final String DEFAULT_EXCEPTION_TRANSLATION_FILTER_ID = "_exceptionTranslationFilter"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public static final String DEFAULT_FILTER_SECURITY_INTERCEPTOR_ID = "_filterSecurityInterceptor"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public static final String DEFAULT_CHANNEL_PROCESSING_FILTER_ID = "_channelProcessingFilter"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public static final String DEFAULT_CHANNEL_DECISION_MANAGER_ID = "_channelDecisionManager"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public static final String CONCURRENT_SESSIONS_ELEMENT = "concurrent-session-control"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public static final String LOGOUT_ELEMENT = "logout"; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -53,6 +67,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     static final String NO_FILTERS_VALUE = "none"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     private static final String ACCESS_CONFIG_ATTRIBUTE = "access"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static final String REQUIRES_CHANNEL_ATTRIBUTE = "requiresChannel"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public BeanDefinition parse(Element element, ParserContext parserContext) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         RootBeanDefinition filterChainProxy = new RootBeanDefinition(FilterChainProxy.class); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -78,10 +93,12 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         String patternType = element.getAttribute(PATTERN_TYPE_ATTRIBUTE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         FilterInvocationDefinitionMap interceptorFilterInvDefSource = new PathBasedFilterInvocationDefinitionMap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        FilterInvocationDefinitionMap channelFilterInvDefSource = new PathBasedFilterInvocationDefinitionMap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (patternType.equals(PATTERN_TYPE_REGEX)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             filterChainProxy.getPropertyValues().addPropertyValue("matcher", new RegexUrlPathMatcher()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             interceptorFilterInvDefSource = new RegExpBasedFilterInvocationDefinitionMap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            channelFilterInvDefSource = new RegExpBasedFilterInvocationDefinitionMap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         filterChainProxy.getPropertyValues().addPropertyValue("filterChainMap", filterChainMap); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -92,7 +109,28 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         //filterSecurityInterceptorBuilder.setAutowireMode(RootBeanDefinition.AUTOWIRE_BY_TYPE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         parseInterceptUrls(DomUtils.getChildElementsByTagName(element, "intercept-url"), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                filterChainMap, interceptorFilterInvDefSource); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                filterChainMap, interceptorFilterInvDefSource, channelFilterInvDefSource, parserContext); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BeanDefinitionRegistry registry = parserContext.getRegistry(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Check if we need to register the channel processing beans 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (((AbstractFilterInvocationDefinitionSource)channelFilterInvDefSource).getMapSize() > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // At least one channel requirement has been specified 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            RootBeanDefinition channelFilter = new RootBeanDefinition(ChannelProcessingFilter.class); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            channelFilter.getPropertyValues().addPropertyValue("channelDecisionManager", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    new RuntimeBeanReference(DEFAULT_CHANNEL_DECISION_MANAGER_ID)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            channelFilter.getPropertyValues().addPropertyValue("filterInvocationDefinitionSource", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    channelFilterInvDefSource); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            RootBeanDefinition channelDecisionManager = new RootBeanDefinition(ChannelDecisionManagerImpl.class); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            List channelProcessors = new ArrayList(2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            channelProcessors.add(new SecureChannelProcessor()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            channelProcessors.add(new InsecureChannelProcessor()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            channelDecisionManager.getPropertyValues().addPropertyValue("channelProcessors", channelProcessors); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            registry.registerBeanDefinition(DEFAULT_CHANNEL_PROCESSING_FILTER_ID, channelFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            registry.registerBeanDefinition(DEFAULT_CHANNEL_DECISION_MANAGER_ID, channelDecisionManager); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Element sessionControlElt = DomUtils.getChildElementByTagName(element, CONCURRENT_SESSIONS_ELEMENT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -100,8 +138,8 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             new ConcurrentSessionsBeanDefinitionParser().parse(sessionControlElt, parserContext); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Parse remember me before logout as RememberMeServices is also a LogoutHandler implementation.  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        BeanDefinitionRegistry registry = parserContext.getRegistry(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Parse remember me before logout as RememberMeServices is also a LogoutHandler implementation. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Element rememberMeElt = DomUtils.getChildElementByTagName(element, REMEMBER_ME_ELEMENT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -149,11 +187,12 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      * FilterInvocationDefinitionSource used in FilterSecurityInterceptor. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     private void parseInterceptUrls(List urlElts, Map filterChainMap, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            FilterInvocationDefinitionMap interceptorFilterInvDefSource) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            FilterInvocationDefinitionMap interceptorFilterInvDefSource, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            FilterInvocationDefinitionMap channelFilterInvDefSource, ParserContext parserContext) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Iterator urlEltsIterator = urlElts.iterator(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ConfigAttributeEditor attributeEditor = new ConfigAttributeEditor(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ConfigAttributeEditor editor = new ConfigAttributeEditor(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         while (urlEltsIterator.hasNext()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             Element urlElt = (Element) urlEltsIterator.next(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -166,18 +205,33 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             // Convert the comma-separated list of access attributes to a ConfigAttributeDefinition 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (StringUtils.hasText(access)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                attributeEditor.setAsText(access); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                editor.setAsText(access); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                interceptorFilterInvDefSource.addSecureUrl(path, (ConfigAttributeDefinition) editor.getValue()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            String requiredChannel = urlElt.getAttribute(REQUIRES_CHANNEL_ATTRIBUTE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ConfigAttributeDefinition attributeDef = (ConfigAttributeDefinition) attributeEditor.getValue(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (StringUtils.hasText(requiredChannel)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                String channelConfigAttribute = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (requiredChannel.equals("https")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    channelConfigAttribute = "REQUIRES_SECURE_CHANNEL"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else if (requiredChannel.equals("http")) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    channelConfigAttribute = "REQUIRES_INSECURE_CHANNEL"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    parserContext.getReaderContext().error("Unsupported channel " + requiredChannel, urlElt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                interceptorFilterInvDefSource.addSecureUrl(path, attributeDef); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                editor.setAsText(channelConfigAttribute); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                channelFilterInvDefSource.addSecureUrl(path, (ConfigAttributeDefinition) editor.getValue()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             String filters = urlElt.getAttribute(FILTERS_ATTRIBUTE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (StringUtils.hasText(filters)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (!filters.equals(NO_FILTERS_VALUE)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    throw new IllegalStateException("Currently only 'none' is supported as the custom filters attribute"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    parserContext.getReaderContext().error("Currently only 'none' is supported as the custom " + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            "filters attribute", urlElt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 filterChainMap.put(path, Collections.EMPTY_LIST); 
			 |