Skip to content

Commit 38f8d65

Browse files
author
Dave Syer
committed
Use ApplicationEvent to ensure that authentication event publisher is registered
There was a reference to an old (fixed) issue in Spring which led to some simplification of the AuthenticationManager layering as well. Fixes gh-1335
1 parent 88828f5 commit 38f8d65

File tree

3 files changed

+43
-9
lines changed

3 files changed

+43
-9
lines changed

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/AuthenticationManagerConfiguration.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@
2626
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
2727
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2828
import org.springframework.boot.autoconfigure.security.SecurityProperties.User;
29+
import org.springframework.context.ApplicationListener;
2930
import org.springframework.context.annotation.Bean;
3031
import org.springframework.context.annotation.Configuration;
3132
import org.springframework.context.annotation.Lazy;
3233
import org.springframework.context.annotation.Primary;
3334
import org.springframework.context.annotation.Scope;
3435
import org.springframework.context.annotation.ScopedProxyMode;
36+
import org.springframework.context.event.ContextRefreshedEvent;
3537
import org.springframework.core.Ordered;
3638
import org.springframework.core.annotation.Order;
3739
import org.springframework.security.authentication.AuthenticationEventPublisher;
@@ -54,7 +56,8 @@
5456
@ConditionalOnMissingBean(AuthenticationManager.class)
5557
@Order(Ordered.LOWEST_PRECEDENCE - 3)
5658
public class AuthenticationManagerConfiguration extends
57-
GlobalAuthenticationConfigurerAdapter {
59+
GlobalAuthenticationConfigurerAdapter implements
60+
ApplicationListener<ContextRefreshedEvent> {
5861

5962
private static Log logger = LogFactory
6063
.getLog(AuthenticationManagerConfiguration.class);
@@ -79,23 +82,23 @@ public void init(AuthenticationManagerBuilder auth) throws Exception {
7982
}
8083

8184
@Bean
82-
// avoid issues with scopedTarget (SPR-11548)
8385
@Primary
86+
@Lazy
87+
@Scope(proxyMode = ScopedProxyMode.INTERFACES)
8488
public AuthenticationManager authenticationManager() {
85-
return lazyAuthenticationManager();
89+
AuthenticationManager manager = this.configurer.getAuthenticationManagerBuilder()
90+
.getOrBuild();
91+
return manager;
8692
}
8793

88-
@Bean
89-
@Lazy
90-
@Scope(proxyMode = ScopedProxyMode.INTERFACES)
91-
protected AuthenticationManager lazyAuthenticationManager() {
94+
@Override
95+
public void onApplicationEvent(ContextRefreshedEvent event) {
9296
AuthenticationManager manager = this.configurer.getAuthenticationManagerBuilder()
9397
.getOrBuild();
9498
if (manager instanceof ProviderManager) {
9599
((ProviderManager) manager)
96100
.setAuthenticationEventPublisher(this.authenticationEventPublisher);
97101
}
98-
return manager;
99102
}
100103

101104
/**

spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SecurityAutoConfigurationTests.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.springframework.boot.autoconfigure.security;
1818

1919
import java.util.List;
20+
import java.util.concurrent.atomic.AtomicReference;
2021

2122
import org.junit.Test;
2223
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
@@ -26,12 +27,17 @@
2627
import org.springframework.boot.autoconfigure.orm.jpa.test.City;
2728
import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration;
2829
import org.springframework.boot.test.EnvironmentTestUtils;
30+
import org.springframework.context.ApplicationEvent;
31+
import org.springframework.context.ApplicationListener;
2932
import org.springframework.context.annotation.Bean;
3033
import org.springframework.context.annotation.Configuration;
3134
import org.springframework.mock.web.MockServletContext;
3235
import org.springframework.orm.jpa.JpaTransactionManager;
3336
import org.springframework.security.authentication.AuthenticationManager;
37+
import org.springframework.security.authentication.BadCredentialsException;
3438
import org.springframework.security.authentication.TestingAuthenticationToken;
39+
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
40+
import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent;
3541
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
3642
import org.springframework.security.core.Authentication;
3743
import org.springframework.security.core.AuthenticationException;
@@ -41,6 +47,8 @@
4147

4248
import static org.junit.Assert.assertEquals;
4349
import static org.junit.Assert.assertNotNull;
50+
import static org.junit.Assert.assertTrue;
51+
import static org.junit.Assert.fail;
4452

4553
/**
4654
* Tests for {@link SecurityAutoConfiguration}.
@@ -104,6 +112,27 @@ public void testAuthenticationManagerCreated() throws Exception {
104112
assertNotNull(this.context.getBean(AuthenticationManager.class));
105113
}
106114

115+
@Test
116+
public void testEventPublisherInjected() throws Exception {
117+
testAuthenticationManagerCreated();
118+
final AtomicReference<ApplicationEvent> wrapper = new AtomicReference<ApplicationEvent>();
119+
this.context.addApplicationListener(new ApplicationListener<ApplicationEvent>() {
120+
@Override
121+
public void onApplicationEvent(ApplicationEvent event) {
122+
wrapper.set(event);
123+
};
124+
});
125+
AuthenticationManager manager = this.context.getBean(AuthenticationManager.class);
126+
try {
127+
manager.authenticate(new UsernamePasswordAuthenticationToken("foo", "bar"));
128+
fail("Expected BadCredentialsException");
129+
}
130+
catch (BadCredentialsException e) {
131+
// expected
132+
}
133+
assertTrue(wrapper.get() instanceof AuthenticationFailureBadCredentialsEvent);
134+
}
135+
107136
@Test
108137
public void testOverrideAuthenticationManager() throws Exception {
109138
this.context = new AnnotationConfigWebApplicationContext();

spring-boot-samples/spring-boot-sample-parent-context/pom.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
34
<modelVersion>4.0.0</modelVersion>
45
<parent>
56
<!-- Your own application should inherit from spring-boot-starter-parent -->
@@ -16,6 +17,7 @@
1617
<url>http://www.spring.io</url>
1718
</organization>
1819
<properties>
20+
<start-class>sample.parent.SampleParentContextApplication</start-class>
1921
<main.basedir>${basedir}/../..</main.basedir>
2022
</properties>
2123
<dependencies>

0 commit comments

Comments
 (0)