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);
}