diff --git a/config/src/main/java/org/springframework/security/config/authentication/AuthenticationManagerBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/authentication/AuthenticationManagerBeanDefinitionParser.java index 90ed110cb4..5e4a30cf63 100644 --- a/config/src/main/java/org/springframework/security/config/authentication/AuthenticationManagerBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/authentication/AuthenticationManagerBeanDefinitionParser.java @@ -35,6 +35,7 @@ import org.w3c.dom.NodeList; public class AuthenticationManagerBeanDefinitionParser implements BeanDefinitionParser { private static final String ATT_ALIAS = "alias"; private static final String ATT_REF = "ref"; + private static final String ATT_ERASE_CREDENTIALS = "erase-credentials"; public BeanDefinition parse(Element element, ParserContext pc) { Assert.state(!pc.getRegistry().containsBeanDefinition(BeanIds.AUTHENTICATION_MANAGER), @@ -72,6 +73,11 @@ public class AuthenticationManagerBeanDefinitionParser implements BeanDefinition } providerManagerBldr.addPropertyValue("providers", providers); + + if ("true".equals(element.getAttribute(ATT_ERASE_CREDENTIALS))) { + providerManagerBldr.addPropertyValue("eraseCredentialsAfterAuthentication", true); + } + // Add the default event publisher BeanDefinition publisher = new RootBeanDefinition(DefaultAuthenticationEventPublisher.class); String id = pc.getReaderContext().generateBeanName(publisher); diff --git a/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java index a58fb35661..148366eb0d 100644 --- a/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java @@ -12,6 +12,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeanMetadataElement; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanReference; +import org.springframework.beans.factory.config.MethodInvokingFactoryBean; import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.parsing.BeanComponentDefinition; import org.springframework.beans.factory.parsing.CompositeComponentDefinition; @@ -166,6 +167,10 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { BeanDefinitionBuilder authManager = BeanDefinitionBuilder.rootBeanDefinition(ProviderManager.class); authManager.addPropertyValue("parent", new RootBeanDefinition(AuthenticationManagerFactoryBean.class)); authManager.addPropertyValue("providers", authenticationProviders); + RootBeanDefinition clearCredentials = new RootBeanDefinition(MethodInvokingFactoryBean.class); + clearCredentials.getPropertyValues().addPropertyValue("targetObject", new RootBeanDefinition(AuthenticationManagerFactoryBean.class)); + clearCredentials.getPropertyValues().addPropertyValue("targetMethod", "isEraseCredentialsAfterAuthentication"); + authManager.addPropertyValue("eraseCredentialsAfterAuthentication", clearCredentials); if (concurrencyController != null) { authManager.addPropertyValue("sessionController", concurrencyController); diff --git a/config/src/main/resources/org/springframework/security/config/spring-security-3.0.3.rnc b/config/src/main/resources/org/springframework/security/config/spring-security-3.0.3.rnc index 6b6fa83557..3981ae283c 100644 --- a/config/src/main/resources/org/springframework/security/config/spring-security-3.0.3.rnc +++ b/config/src/main/resources/org/springframework/security/config/spring-security-3.0.3.rnc @@ -544,6 +544,9 @@ authentication-manager = authman.attlist &= ## The alias you wish to use for the AuthenticationManager bean attribute alias {xsd:ID}? +authman.attlist &= + ## If set to true, the AuthenticationManger will attempt to clear any credentials data in the returned Authentication object, once the user has been authenticated. Defaults to false. + attribute erase-credentials {boolean}? authentication-provider = ## Indicates that the contained user-service should be used as an authentication source. diff --git a/config/src/main/resources/org/springframework/security/config/spring-security-3.0.3.xsd b/config/src/main/resources/org/springframework/security/config/spring-security-3.0.3.xsd index 5e06259693..27bd5be598 100644 --- a/config/src/main/resources/org/springframework/security/config/spring-security-3.0.3.xsd +++ b/config/src/main/resources/org/springframework/security/config/spring-security-3.0.3.xsd @@ -1201,6 +1201,11 @@ The alias you wish to use for the AuthenticationManager bean + + + If set to true, the AuthenticationManger will attempt to clear any credentials data in the returned Authentication object, once the user has been authenticated. Defaults to false. + + diff --git a/config/src/test/java/org/springframework/security/config/authentication/AuthenticationManagerBeanDefinitionParserTests.java b/config/src/test/java/org/springframework/security/config/authentication/AuthenticationManagerBeanDefinitionParserTests.java index c63e43735f..142d200df1 100644 --- a/config/src/test/java/org/springframework/security/config/authentication/AuthenticationManagerBeanDefinitionParserTests.java +++ b/config/src/test/java/org/springframework/security/config/authentication/AuthenticationManagerBeanDefinitionParserTests.java @@ -53,6 +53,20 @@ public class AuthenticationManagerBeanDefinitionParserTests { assertEquals(1, listener.events.size()); } + @Test + public void credentialsAreClearedByDefault() throws Exception { + setContext(CONTEXT, "3.1"); + ProviderManager pm = (ProviderManager) appContext.getBeansOfType(ProviderManager.class).values().toArray()[0]; + assertTrue(pm.isEraseCredentialsAfterAuthentication()); + } + + @Test + public void clearCredentialsPropertyIsRespected() throws Exception { + setContext("", "3.1"); + ProviderManager pm = (ProviderManager) appContext.getBeansOfType(ProviderManager.class).values().toArray()[0]; + assertFalse(pm.isEraseCredentialsAfterAuthentication()); + } + private void setContext(String context, String version) { appContext = new InMemoryXmlApplicationContext(context, version, null); }