package org.springframework.security.config;

import org.springframework.security.ui.preauth.PreAuthenticatedProcessingFilterEntryPoint;
import org.springframework.security.ui.preauth.x509.X509PreAuthenticatedProcessingFilter;
import org.springframework.security.ui.preauth.x509.SubjectDnX509PrincipalExtractor;
import org.springframework.security.providers.preauth.PreAuthenticatedAuthenticationProvider;
import org.springframework.security.providers.preauth.UserDetailsByNameServiceWrapper;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
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.RootBeanDefinition;
import org.springframework.util.StringUtils;

import org.w3c.dom.Element;

/**
 * Parses x509 element in namespace, registering an {@link X509PreAuthenticatedProcessingFilter} instance and a
 * {@link PreAuthenticatedProcessingFilterEntryPoint}.
 *
 * @author Luke Taylor
 * @version $Id$
 * @since 2.0
 */
public class X509BeanDefinitionParser implements BeanDefinitionParser {
    public static final String ATT_REGEX = "subject-principal-regex";
    public static final String ATT_USER_SERVICE_REF = "user-service-ref";

    public BeanDefinition parse(Element element, ParserContext parserContext) {
        BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder.rootBeanDefinition(X509PreAuthenticatedProcessingFilter.class);
	    RootBeanDefinition entryPoint = new RootBeanDefinition(PreAuthenticatedProcessingFilterEntryPoint.class);

        String regex = element.getAttribute(ATT_REGEX);

        if (StringUtils.hasText(regex)) {
            SubjectDnX509PrincipalExtractor extractor = new SubjectDnX509PrincipalExtractor();
            extractor.setSubjectDnRegex(regex);

            filterBuilder.addPropertyValue("principalExtractor", extractor);
        }

        BeanDefinition provider = new RootBeanDefinition(PreAuthenticatedAuthenticationProvider.class);
        ConfigUtils.getRegisteredProviders(parserContext).add(provider);
        parserContext.getRegistry().registerBeanDefinition(BeanIds.X509_AUTH_PROVIDER, provider);

        String userServiceRef = element.getAttribute(ATT_USER_SERVICE_REF);

        if (StringUtils.hasText(userServiceRef)) {
            RuntimeBeanReference userService = new RuntimeBeanReference(userServiceRef);
            BeanDefinition preAuthUserService = new RootBeanDefinition(UserDetailsByNameServiceWrapper.class);
            preAuthUserService.getPropertyValues().addPropertyValue("userDetailsService", userService);
            provider.getPropertyValues().addPropertyValue("preAuthenticatedUserDetailsService", preAuthUserService);
        }

	    parserContext.getRegistry().registerBeanDefinition(BeanIds.PRE_AUTH_ENTRY_POINT, entryPoint);

	    filterBuilder.addPropertyValue("authenticationManager", new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER));

	    parserContext.getRegistry().registerBeanDefinition(BeanIds.X509_FILTER, filterBuilder.getBeanDefinition());

	    return null;
    }
}

@@ -482,24 +482,116 @@
 iceWrapper;%0A
+import org.springframework.security.userdetails.decorator.StatusCheckingUserDetailsService;%0A
 import org.s
@@ -2580,41 +2580,213 @@
    R
-untime
+ootBeanDefinition statusCheckingUserService = new Root
 Bean
-Reference userService =
+Definition(StatusCheckingUserDetailsService.class);%0A            statusCheckingUserService.getConstructorArgumentValues().addIndexedArgumentValue(0,
  new
@@ -2822,16 +2822,17 @@
 viceRef)
+)
 ;%0A      
@@ -3026,17 +3026,31 @@
 rvice%22, 
-u
+statusCheckingU
 serServi

Update new X509 namespace config to use status checking of user accounts by default.