Set AuthenticationEventPublisher on each AuthenticationManagerBuilder

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

View File

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

View File

@ -21,6 +21,7 @@ import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
@ -28,6 +29,7 @@ import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
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.WebSecurityConfigurerAdapter;
@ -156,6 +158,30 @@ public class OAuth2LoginConfigurerTests {
.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
public void oauth2LoginWhenAuthenticatedThenIgnored() throws Exception {
// setup application context
@ -467,7 +493,9 @@ public class OAuth2LoginConfigurerTests {
}
@EnableWebSecurity
static class OAuth2LoginConfig extends CommonWebSecurityConfigurerAdapter {
static class OAuth2LoginConfig extends CommonWebSecurityConfigurerAdapter implements ApplicationListener<AuthenticationSuccessEvent> {
static List<AuthenticationSuccessEvent> EVENTS = new ArrayList<>();
@Override
protected void configure(HttpSecurity http) throws Exception {
http
@ -476,6 +504,11 @@ public class OAuth2LoginConfigurerTests {
new InMemoryClientRegistrationRepository(GOOGLE_CLIENT_REGISTRATION));
super.configure(http);
}
@Override
public void onApplicationEvent(AuthenticationSuccessEvent event) {
EVENTS.add(event);
}
}
@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");
* 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
* limitations under the License.
*/
package org.springframework.security.authentication;
import java.util.Collections;
@ -158,6 +157,7 @@ public class ProviderManager implements AuthenticationManager, MessageSourceAwar
Class<? extends Authentication> toTest = authentication.getClass();
AuthenticationException lastException = null;
Authentication result = null;
Authentication parentResult = null;
boolean debug = logger.isDebugEnabled();
for (AuthenticationProvider provider : getProviders()) {
@ -196,7 +196,7 @@ public class ProviderManager implements AuthenticationManager, MessageSourceAwar
if (result == null && parent != null) {
// Allow the parent to try.
try {
result = parent.authenticate(authentication);
result = parentResult = parent.authenticate(authentication);
}
catch (ProviderNotFoundException e) {
// 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();
}
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;
}