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 a2df060abf1..965a6ee2a95 100644
--- a/core/src/main/java/org/springframework/security/authentication/DefaultAuthenticationEventPublisher.java
+++ b/core/src/main/java/org/springframework/security/authentication/DefaultAuthenticationEventPublisher.java
@@ -149,7 +149,10 @@ public void setApplicationEventPublisher(
* @param additionalExceptionMappings where keys are the fully-qualified string name
* of the exception class and the values are the fully-qualified string name of the
* event class to fire.
+ *
+ * @deprecated use {@link #setAdditionalExceptionMappings(Map)}
*/
+ @Deprecated
@SuppressWarnings({ "unchecked" })
public void setAdditionalExceptionMappings(Properties additionalExceptionMappings) {
Assert.notNull(additionalExceptionMappings,
@@ -169,6 +172,26 @@ public void setAdditionalExceptionMappings(Properties additionalExceptionMapping
}
}
+ /**
+ * Sets additional exception to event mappings. These are automatically merged with
+ * the default exception to event mappings that ProviderManager
defines.
+ *
+ * @param mappings where keys are exception classes and values are event classes.
+ * @since 5.3
+ */
+ public void setAdditionalExceptionMappings(Map,
+ Class extends AbstractAuthenticationFailureEvent>> mappings){
+ Assert.notEmpty(mappings, "The mappings Map must not be empty nor null");
+ for (Map.Entry, Class extends AbstractAuthenticationFailureEvent>> entry
+ : mappings.entrySet()) {
+ Class> exceptionClass = entry.getKey();
+ Class> eventClass = entry.getValue();
+ Assert.notNull(exceptionClass, "exceptionClass cannot be null");
+ Assert.notNull(eventClass, "eventClass cannot be null");
+ addMapping(exceptionClass.getName(), (Class extends AbstractAuthenticationFailureEvent>) eventClass);
+ }
+ }
+
/**
* Sets a default authentication failure event as a fallback event for any unmapped
* exceptions not mapped in the exception mappings.
diff --git a/core/src/test/java/org/springframework/security/authentication/DefaultAuthenticationEventPublisherTests.java b/core/src/test/java/org/springframework/security/authentication/DefaultAuthenticationEventPublisherTests.java
index 4750ee51496..9c0c14993e3 100644
--- a/core/src/test/java/org/springframework/security/authentication/DefaultAuthenticationEventPublisherTests.java
+++ b/core/src/test/java/org/springframework/security/authentication/DefaultAuthenticationEventPublisherTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2020 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.
@@ -19,6 +19,7 @@
import org.junit.*;
import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent;
import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent;
import org.springframework.security.authentication.event.AuthenticationFailureCredentialsExpiredEvent;
import org.springframework.security.authentication.event.AuthenticationFailureDisabledEvent;
@@ -138,6 +139,47 @@ public void unknownFailureExceptionIsIgnored() {
verifyZeroInteractions(appPublisher);
}
+ @Test(expected = IllegalArgumentException.class)
+ public void emptyMapCausesException() {
+ Map,
+ Class extends AbstractAuthenticationFailureEvent>> mappings = new HashMap<>();
+ publisher = new DefaultAuthenticationEventPublisher();
+ publisher.setAdditionalExceptionMappings(mappings);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void missingExceptionClassCausesException() {
+ Map,
+ Class extends AbstractAuthenticationFailureEvent>> mappings = new HashMap<>();
+ mappings.put(null, AuthenticationFailureLockedEvent.class);
+ publisher = new DefaultAuthenticationEventPublisher();
+ publisher.setAdditionalExceptionMappings(mappings);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void missingEventClassAsMapValueCausesException() {
+ Map,
+ Class extends AbstractAuthenticationFailureEvent>> mappings = new HashMap<>();
+ mappings.put(LockedException.class, null);
+ publisher = new DefaultAuthenticationEventPublisher();
+ publisher.setAdditionalExceptionMappings(mappings);
+ }
+
+ @Test
+ public void additionalExceptionMappingsUsingMapAreSupported() {
+ publisher = new DefaultAuthenticationEventPublisher();
+ Map,
+ Class extends AbstractAuthenticationFailureEvent>> mappings = new HashMap<>();
+ mappings.put(MockAuthenticationException.class,AuthenticationFailureDisabledEvent.class);
+ publisher.setAdditionalExceptionMappings(mappings);
+ ApplicationEventPublisher appPublisher = mock(ApplicationEventPublisher.class);
+
+ publisher.setApplicationEventPublisher(appPublisher);
+ publisher.publishAuthenticationFailure(new MockAuthenticationException("test"),
+ mock(Authentication.class));
+ verify(appPublisher).publishEvent(isA(AuthenticationFailureDisabledEvent.class));
+ }
+
@Test(expected = IllegalArgumentException.class)
public void defaultAuthenticationFailureEventClassSetNullThen() {
publisher = new DefaultAuthenticationEventPublisher();