Set AuthenticationEventPublisher on each AuthenticationManagerBuilder

Fixes gh-6009
This commit is contained in:
Joe Grandja 2018-10-23 14:08:23 -04:00
parent 0c32cbd862
commit d6da4d20b4
3 changed files with 43 additions and 5 deletions

View File

@ -200,6 +200,7 @@ public abstract class WebSecurityConfigurerAdapter implements
AuthenticationManager authenticationManager = authenticationManager(); AuthenticationManager authenticationManager = authenticationManager();
authenticationBuilder.parentAuthenticationManager(authenticationManager); authenticationBuilder.parentAuthenticationManager(authenticationManager);
authenticationBuilder.authenticationEventPublisher(eventPublisher);
Map<Class<? extends Object>, Object> sharedObjects = createSharedObjects(); Map<Class<? extends Object>, Object> sharedObjects = createSharedObjects();
http = new HttpSecurity(objectPostProcessor, authenticationBuilder, http = new HttpSecurity(objectPostProcessor, authenticationBuilder,

View File

@ -20,11 +20,13 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.PropertyAccessorFactory; import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.mock.web.MockFilterChain; import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@ -145,6 +147,30 @@ public class OAuth2LoginConfigurerTests {
.isInstanceOf(OAuth2UserAuthority.class).hasToString("ROLE_USER"); .isInstanceOf(OAuth2UserAuthority.class).hasToString("ROLE_USER");
} }
// gh-6009
@Test
public void oauth2LoginWhenSuccessThenAuthenticationSuccessEventPublished() throws Exception {
// setup application context
loadConfig(OAuth2LoginConfig.class);
// setup authorization request
OAuth2AuthorizationRequest authorizationRequest = createOAuth2AuthorizationRequest();
this.authorizationRequestRepository.saveAuthorizationRequest(
authorizationRequest, this.request, this.response);
// setup authentication parameters
this.request.setParameter("code", "code123");
this.request.setParameter("state", authorizationRequest.getState());
// perform test
this.springSecurityFilterChain.doFilter(this.request, this.response, this.filterChain);
// assertions
assertThat(OAuth2LoginConfig.EVENTS).isNotEmpty();
assertThat(OAuth2LoginConfig.EVENTS).hasSize(1);
assertThat(OAuth2LoginConfig.EVENTS.get(0)).isInstanceOf(AuthenticationSuccessEvent.class);
}
@Test @Test
public void oauth2LoginCustomWithConfigurer() throws Exception { public void oauth2LoginCustomWithConfigurer() throws Exception {
// setup application context // setup application context
@ -348,7 +374,9 @@ public class OAuth2LoginConfigurerTests {
} }
@EnableWebSecurity @EnableWebSecurity
static class OAuth2LoginConfig extends CommonWebSecurityConfigurerAdapter { static class OAuth2LoginConfig extends CommonWebSecurityConfigurerAdapter implements ApplicationListener<AuthenticationSuccessEvent> {
static List<AuthenticationSuccessEvent> EVENTS = new ArrayList<>();
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http http
@ -357,6 +385,11 @@ public class OAuth2LoginConfigurerTests {
new InMemoryClientRegistrationRepository(CLIENT_REGISTRATION)); new InMemoryClientRegistrationRepository(CLIENT_REGISTRATION));
super.configure(http); super.configure(http);
} }
@Override
public void onApplicationEvent(AuthenticationSuccessEvent event) {
EVENTS.add(event);
}
} }
@EnableWebSecurity @EnableWebSecurity

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.security.authentication; package org.springframework.security.authentication;
import java.util.Collections; import java.util.Collections;
@ -158,6 +157,7 @@ public class ProviderManager implements AuthenticationManager, MessageSourceAwar
Class<? extends Authentication> toTest = authentication.getClass(); Class<? extends Authentication> toTest = authentication.getClass();
AuthenticationException lastException = null; AuthenticationException lastException = null;
Authentication result = null; Authentication result = null;
Authentication parentResult = null;
boolean debug = logger.isDebugEnabled(); boolean debug = logger.isDebugEnabled();
for (AuthenticationProvider provider : getProviders()) { for (AuthenticationProvider provider : getProviders()) {
@ -196,7 +196,7 @@ public class ProviderManager implements AuthenticationManager, MessageSourceAwar
if (result == null && parent != null) { if (result == null && parent != null) {
// Allow the parent to try. // Allow the parent to try.
try { try {
result = parent.authenticate(authentication); result = parentResult = parent.authenticate(authentication);
} }
catch (ProviderNotFoundException e) { catch (ProviderNotFoundException e) {
// ignore as we will throw below if no other exception occurred prior to // ignore as we will throw below if no other exception occurred prior to
@ -217,7 +217,11 @@ public class ProviderManager implements AuthenticationManager, MessageSourceAwar
((CredentialsContainer) result).eraseCredentials(); ((CredentialsContainer) result).eraseCredentials();
} }
eventPublisher.publishAuthenticationSuccess(result); // If the parent AuthenticationManager was attempted and successful than it will publish an AuthenticationSuccessEvent
// This check prevents a duplicate AuthenticationSuccessEvent if the parent AuthenticationManager already published it
if (parentResult == null) {
eventPublisher.publishAuthenticationSuccess(result);
}
return result; return result;
} }