From d4d5012035374b9f4e92ef3f3435cb6b044a0708 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Tue, 17 Nov 2009 12:55:53 +0000 Subject: [PATCH] SEC-1272: does not register default event handler DefaultAuthenticationEventPublisher. Update AuthenticationManagerBeanDefinitionParser to register a DefaultAuthenticationeventPublisher and set it on the registered ProviderManager. --- ...enticationManagerBeanDefinitionParser.java | 6 +++ ...ationManagerBeanDefinitionParserTests.java | 52 +++++++++++++++---- .../DefaultAuthenticationEventPublisher.java | 2 +- 3 files changed, 50 insertions(+), 10 deletions(-) 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 9806fecbcb..92931f2b5d 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 @@ -14,6 +14,7 @@ import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.NamespaceHandlerResolver; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.DefaultAuthenticationEventPublisher; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.config.BeanIds; import org.springframework.security.core.Authentication; @@ -72,6 +73,11 @@ public class AuthenticationManagerBeanDefinitionParser implements BeanDefinition } providerManagerBldr.addPropertyValue("providers", providers); + // Add the default event publisher + BeanDefinition publisher = new RootBeanDefinition(DefaultAuthenticationEventPublisher.class); + String id = pc.getReaderContext().registerWithGeneratedName(publisher); + pc.registerBeanComponent(new BeanComponentDefinition(publisher, id)); + providerManagerBldr.addPropertyReference("authenticationEventPublisher", id); BeanDefinition authManager = providerManagerBldr.getBeanDefinition(); pc.getRegistry().registerBeanDefinition(BeanIds.AUTHENTICATION_MANAGER, authManager); 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 c488d8acf1..bf6782c9a7 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 @@ -1,11 +1,20 @@ package org.springframework.security.config.authentication; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.List; import org.junit.Test; +import org.springframework.context.ApplicationListener; import org.springframework.context.support.AbstractXmlApplicationContext; import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.DefaultAuthenticationEventPublisher; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.authentication.event.AbstractAuthenticationEvent; import org.springframework.security.config.util.InMemoryXmlApplicationContext; +import org.springframework.security.util.FieldUtils; /** * @@ -13,23 +22,48 @@ import org.springframework.security.config.util.InMemoryXmlApplicationContext; * @version $Id$ */ public class AuthenticationManagerBeanDefinitionParserTests { + private static final String CONTEXT = + "" + + " " + + " " + + " " + + " " + + " " + + ""; private AbstractXmlApplicationContext appContext; @Test // SEC-1225 public void providersAreRegisteredAsTopLevelBeans() throws Exception { - setContext( - "" + - " " + - " " + - " " + - " " + - " " + - "", "3.0"); + setContext(CONTEXT, "3.0"); assertEquals(1, appContext.getBeansOfType(AuthenticationProvider.class).size()); } + @Test + public void eventsArePublishedByDefault() throws Exception { + setContext(CONTEXT, "3.0"); + AuthListener listener = new AuthListener(); + appContext.addApplicationListener(listener); + appContext.refresh(); + + ProviderManager pm = (ProviderManager) appContext.getBeansOfType(ProviderManager.class).values().toArray()[0]; + Object eventPublisher = FieldUtils.getFieldValue(pm, "eventPublisher"); + assertNotNull(eventPublisher); + assertTrue(eventPublisher instanceof DefaultAuthenticationEventPublisher); + + pm.authenticate(new UsernamePasswordAuthenticationToken("bob", "bobspassword")); + assertEquals(1, listener.events.size()); + } + private void setContext(String context, String version) { appContext = new InMemoryXmlApplicationContext(context, version, null); } + + private static class AuthListener implements ApplicationListener { + List events = new ArrayList(); + + public void onApplicationEvent(AbstractAuthenticationEvent event) { + events.add(event); + } + } } diff --git a/core/src/main/java/org/springframework/security/authentication/DefaultAuthenticationEventPublisher.java b/core/src/main/java/org/springframework/security/authentication/DefaultAuthenticationEventPublisher.java index 6732e40420..addb297002 100644 --- a/core/src/main/java/org/springframework/security/authentication/DefaultAuthenticationEventPublisher.java +++ b/core/src/main/java/org/springframework/security/authentication/DefaultAuthenticationEventPublisher.java @@ -24,7 +24,7 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.util.Assert; /** - * The default strategy used by ProviderManager for publishing authentication events. + * The default strategy for publishing authentication events. *

* Maps well-known AuthenticationException types to events and publishes them via the * application context. If configured as a bean, it will pick up the ApplicationEventPublisher automatically.