Uploaded image for project: 'Spring Security'
  1. Spring Security
  2. SEC-2919

DefaultLoginGeneratingFilter incorrectly used if login-url="/login"

    XMLWordPrintable

Details

    • Bug
    • Status: Closed
    • Critical
    • Resolution: Fixed
    • 4.0.0
    • 4.0.1
    • Namespace
    • None

    Description

      If an application specifies [email protected]="/login" then the DefaultLoginGeneratingFilter is incorrectly used. This means that the custom login page cannot be specified with the URL "/login". For example:

      <http ...>
      	<form-login login-page="/login" ... />
      </http>
      

      Workaround

      Using a different URL

      One workaround is to use a different URL for the login page. For example, one could use "/authenticate".

      Using a BeanDefinitionRegistryPostProcessor

      Alternatively, the following BeanDefinitionRegistryPostProcessor will fix the issue by removing the DefaultLoginPageGeneratingFilter. To use it simply ensure to register the BeanDefinitionRegistryPostProcessor as a Bean.

      import java.util.Iterator;
      import java.util.List;
      
      import org.springframework.beans.BeansException;
      import org.springframework.beans.factory.config.BeanDefinition;
      import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
      import org.springframework.beans.factory.support.BeanDefinitionRegistry;
      import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
      import org.springframework.security.web.DefaultSecurityFilterChain;
      import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
      
      public class Sec2919PostProcessor implements BeanDefinitionRegistryPostProcessor {
      	@Override
      	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
      			throws BeansException {
      		String[] beanDefinitionNames = registry.getBeanDefinitionNames();
      		for(String name : beanDefinitionNames) {
      			BeanDefinition beanDefinition = registry.getBeanDefinition(name);
      			if(beanDefinition.getBeanClassName().equals(DefaultSecurityFilterChain.class.getName())) {
      				List<Object> filters = (List<Object>) beanDefinition.getConstructorArgumentValues().getArgumentValue(1, List.class).getValue();
      				Iterator<Object> iFilters = filters.iterator();
      				while(iFilters.hasNext()) {
      					Object f = iFilters.next();
      					if(f instanceof BeanDefinition) {
      						BeanDefinition bean = (BeanDefinition) f;
      						if(bean.getBeanClassName().equals(DefaultLoginPageGeneratingFilter.class.getName())) {
      							iFilters.remove();
      						}
      					}
      				}
      			}
      		}
      	}
      
      	@Override
      	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
      			throws BeansException {
      	}
      }
      

      Attachments

        Issue Links

          Activity

            People

              rwinch Rob Winch
              rwinch Rob Winch
              Votes:
              4 Vote for this issue
              Watchers:
              8 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: