Narrow range of events listened for in security audit

The InteractiveAuthenticationSuccessEvent is always shadowed by a
regulat AuthenticationSuccessEvent, so there's no need to listen for
all AbstractAuthenticationSuccessEvents.

Fixes gh-4355
pull/4251/merge
Dave Syer 9 years ago
parent 2cfb6fe0f5
commit cc3f673874

@ -26,6 +26,7 @@ import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ApplicationListener; import org.springframework.context.ApplicationListener;
import org.springframework.security.authentication.event.AbstractAuthenticationEvent; import org.springframework.security.authentication.event.AbstractAuthenticationEvent;
import org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent; import org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.security.web.authentication.switchuser.AuthenticationSwitchUserEvent; import org.springframework.security.web.authentication.switchuser.AuthenticationSwitchUserEvent;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
@ -64,8 +65,8 @@ public class AuthenticationAuditListener implements
else if (this.webListener != null && this.webListener.accepts(event)) { else if (this.webListener != null && this.webListener.accepts(event)) {
this.webListener.process(this, event); this.webListener.process(this, event);
} }
else { else if (event instanceof AuthenticationSuccessEvent) {
onAuthenticationEvent(event); onAuthenticationEvent((AuthenticationSuccessEvent) event);
} }
} }
@ -77,7 +78,7 @@ public class AuthenticationAuditListener implements
"AUTHENTICATION_FAILURE", data)); "AUTHENTICATION_FAILURE", data));
} }
private void onAuthenticationEvent(AbstractAuthenticationEvent event) { private void onAuthenticationEvent(AuthenticationSuccessEvent event) {
Map<String, Object> data = new HashMap<String, Object>(); Map<String, Object> data = new HashMap<String, Object>();
if (event.getAuthentication().getDetails() != null) { if (event.getAuthentication().getDetails() != null) {
data.put("details", event.getAuthentication().getDetails()); data.put("details", event.getAuthentication().getDetails());

@ -18,19 +18,20 @@ package org.springframework.boot.actuate.security;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.event.AuthenticationFailureExpiredEvent; import org.springframework.security.authentication.event.AuthenticationFailureExpiredEvent;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent; import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;
import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.switchuser.AuthenticationSwitchUserEvent; import org.springframework.security.web.authentication.switchuser.AuthenticationSwitchUserEvent;
import static org.mockito.Matchers.anyObject; import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
/** /**
@ -55,6 +56,14 @@ public class AuthenticationAuditListenerTests {
verify(this.publisher).publishEvent((ApplicationEvent) anyObject()); verify(this.publisher).publishEvent((ApplicationEvent) anyObject());
} }
@Test
public void testOtherAuthenticationSuccess() {
this.listener.onApplicationEvent(new InteractiveAuthenticationSuccessEvent(
new UsernamePasswordAuthenticationToken("user", "password"), getClass()));
// No need to audit this one (it shadows a regular AuthenticationSuccessEvent)
verify(this.publisher, never()).publishEvent((ApplicationEvent) anyObject());
}
@Test @Test
public void testAuthenticationFailed() { public void testAuthenticationFailed() {
this.listener.onApplicationEvent(new AuthenticationFailureExpiredEvent( this.listener.onApplicationEvent(new AuthenticationFailureExpiredEvent(

@ -2,4 +2,5 @@ spring.thymeleaf.cache: false
security.basic.enabled: false security.basic.enabled: false
# demo only: # demo only:
security.user.password: password security.user.password: password
logging.level.org.springframework.security: INFO logging.level.org.springframework.security: INFO
logging.level.org.springframework.boot.actuate.audit.listener.AuditListener: DEBUG
Loading…
Cancel
Save