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
This commit is contained in:
parent
88828f5097
commit
38f8d65756
|
@ -26,12 +26,14 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.security.SecurityProperties.User;
|
import org.springframework.boot.autoconfigure.security.SecurityProperties.User;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.context.annotation.Scope;
|
import org.springframework.context.annotation.Scope;
|
||||||
import org.springframework.context.annotation.ScopedProxyMode;
|
import org.springframework.context.annotation.ScopedProxyMode;
|
||||||
|
import org.springframework.context.event.ContextRefreshedEvent;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.security.authentication.AuthenticationEventPublisher;
|
import org.springframework.security.authentication.AuthenticationEventPublisher;
|
||||||
|
@ -54,7 +56,8 @@ import org.springframework.security.config.annotation.authentication.configurers
|
||||||
@ConditionalOnMissingBean(AuthenticationManager.class)
|
@ConditionalOnMissingBean(AuthenticationManager.class)
|
||||||
@Order(Ordered.LOWEST_PRECEDENCE - 3)
|
@Order(Ordered.LOWEST_PRECEDENCE - 3)
|
||||||
public class AuthenticationManagerConfiguration extends
|
public class AuthenticationManagerConfiguration extends
|
||||||
GlobalAuthenticationConfigurerAdapter {
|
GlobalAuthenticationConfigurerAdapter implements
|
||||||
|
ApplicationListener<ContextRefreshedEvent> {
|
||||||
|
|
||||||
private static Log logger = LogFactory
|
private static Log logger = LogFactory
|
||||||
.getLog(AuthenticationManagerConfiguration.class);
|
.getLog(AuthenticationManagerConfiguration.class);
|
||||||
|
@ -79,23 +82,23 @@ public class AuthenticationManagerConfiguration extends
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
// avoid issues with scopedTarget (SPR-11548)
|
|
||||||
@Primary
|
@Primary
|
||||||
public AuthenticationManager authenticationManager() {
|
|
||||||
return lazyAuthenticationManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Scope(proxyMode = ScopedProxyMode.INTERFACES)
|
@Scope(proxyMode = ScopedProxyMode.INTERFACES)
|
||||||
protected AuthenticationManager lazyAuthenticationManager() {
|
public AuthenticationManager authenticationManager() {
|
||||||
|
AuthenticationManager manager = this.configurer.getAuthenticationManagerBuilder()
|
||||||
|
.getOrBuild();
|
||||||
|
return manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ContextRefreshedEvent event) {
|
||||||
AuthenticationManager manager = this.configurer.getAuthenticationManagerBuilder()
|
AuthenticationManager manager = this.configurer.getAuthenticationManagerBuilder()
|
||||||
.getOrBuild();
|
.getOrBuild();
|
||||||
if (manager instanceof ProviderManager) {
|
if (manager instanceof ProviderManager) {
|
||||||
((ProviderManager) manager)
|
((ProviderManager) manager)
|
||||||
.setAuthenticationEventPublisher(this.authenticationEventPublisher);
|
.setAuthenticationEventPublisher(this.authenticationEventPublisher);
|
||||||
}
|
}
|
||||||
return manager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package org.springframework.boot.autoconfigure.security;
|
package org.springframework.boot.autoconfigure.security;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||||
|
@ -26,12 +27,17 @@ import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfigurat
|
||||||
import org.springframework.boot.autoconfigure.orm.jpa.test.City;
|
import org.springframework.boot.autoconfigure.orm.jpa.test.City;
|
||||||
import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration;
|
import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration;
|
||||||
import org.springframework.boot.test.EnvironmentTestUtils;
|
import org.springframework.boot.test.EnvironmentTestUtils;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.mock.web.MockServletContext;
|
import org.springframework.mock.web.MockServletContext;
|
||||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.BadCredentialsException;
|
||||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent;
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.AuthenticationException;
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
@ -41,6 +47,8 @@ import org.springframework.web.context.support.AnnotationConfigWebApplicationCon
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link SecurityAutoConfiguration}.
|
* Tests for {@link SecurityAutoConfiguration}.
|
||||||
|
@ -104,6 +112,27 @@ public class SecurityAutoConfigurationTests {
|
||||||
assertNotNull(this.context.getBean(AuthenticationManager.class));
|
assertNotNull(this.context.getBean(AuthenticationManager.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEventPublisherInjected() throws Exception {
|
||||||
|
testAuthenticationManagerCreated();
|
||||||
|
final AtomicReference<ApplicationEvent> wrapper = new AtomicReference<ApplicationEvent>();
|
||||||
|
this.context.addApplicationListener(new ApplicationListener<ApplicationEvent>() {
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(ApplicationEvent event) {
|
||||||
|
wrapper.set(event);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
AuthenticationManager manager = this.context.getBean(AuthenticationManager.class);
|
||||||
|
try {
|
||||||
|
manager.authenticate(new UsernamePasswordAuthenticationToken("foo", "bar"));
|
||||||
|
fail("Expected BadCredentialsException");
|
||||||
|
}
|
||||||
|
catch (BadCredentialsException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
assertTrue(wrapper.get() instanceof AuthenticationFailureBadCredentialsEvent);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOverrideAuthenticationManager() throws Exception {
|
public void testOverrideAuthenticationManager() throws Exception {
|
||||||
this.context = new AnnotationConfigWebApplicationContext();
|
this.context = new AnnotationConfigWebApplicationContext();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<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">
|
<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">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
<!-- Your own application should inherit from spring-boot-starter-parent -->
|
<!-- Your own application should inherit from spring-boot-starter-parent -->
|
||||||
|
@ -16,6 +17,7 @@
|
||||||
<url>http://www.spring.io</url>
|
<url>http://www.spring.io</url>
|
||||||
</organization>
|
</organization>
|
||||||
<properties>
|
<properties>
|
||||||
|
<start-class>sample.parent.SampleParentContextApplication</start-class>
|
||||||
<main.basedir>${basedir}/../..</main.basedir>
|
<main.basedir>${basedir}/../..</main.basedir>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
Loading…
Reference in New Issue