@ -1,27 +1,39 @@
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 attribut eE ditor = new ConfigAttributeEditor ( ) ;
ConfigAttributeEditor editor = new ConfigAttributeEditor ( ) ;
while ( urlEltsIterator . hasNext ( ) ) {
Element urlElt = ( Element ) urlEltsIterator . next ( ) ;
@ -166,18 +205,33 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
@@ -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 ) ;