From d87bec11fb0ebdab9f6d5fe149cd95ba0022ba0c Mon Sep 17 00:00:00 2001 From: Vedran Pavic Date: Thu, 8 Sep 2016 21:33:56 +0200 Subject: [PATCH] Include AuditEvent details in AuditListener Update `AuthorizationAuditListener` to include `AuditEvent` data if found. Closes gh-6851 --- .../security/AuthorizationAuditListener.java | 5 ++- .../AuthorizationAuditListenerTests.java | 33 +++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthorizationAuditListener.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthorizationAuditListener.java index a71d1c49b7..06e6c189bc 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthorizationAuditListener.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthorizationAuditListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 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. @@ -54,6 +54,9 @@ public class AuthorizationAuditListener extends AbstractAuthorizationAuditListen Map data = new HashMap(); data.put("type", event.getAccessDeniedException().getClass().getName()); data.put("message", event.getAccessDeniedException().getMessage()); + if (event.getAuthentication().getDetails() != null) { + data.put("details", event.getAuthentication().getDetails()); + } publish(new AuditEvent(event.getAuthentication().getName(), "AUTHORIZATION_FAILURE", data)); } diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/security/AuthorizationAuditListenerTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/security/AuthorizationAuditListenerTests.java index 222e3b37cd..725b1b24e1 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/security/AuthorizationAuditListenerTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/security/AuthorizationAuditListenerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 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. @@ -20,15 +20,20 @@ import java.util.Arrays; import org.junit.Before; import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.springframework.boot.actuate.audit.listener.AuditApplicationEvent; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEventPublisher; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; +import org.springframework.security.access.event.AuthenticationCredentialsNotFoundEvent; import org.springframework.security.access.event.AuthorizationFailureEvent; +import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Matchers.anyObject; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -49,7 +54,15 @@ public class AuthorizationAuditListenerTests { } @Test - public void testAuthenticationSuccess() { + public void testAuthenticationCredentialsNotFound() { + this.listener.onApplicationEvent(new AuthenticationCredentialsNotFoundEvent(this, + Arrays.asList(new SecurityConfig("USER")), + new AuthenticationCredentialsNotFoundException("Bad user"))); + verify(this.publisher).publishEvent((ApplicationEvent) anyObject()); + } + + @Test + public void testAuthorizationFailure() { this.listener.onApplicationEvent(new AuthorizationFailureEvent(this, Arrays.asList(new SecurityConfig("USER")), new UsernamePasswordAuthenticationToken("user", "password"), @@ -57,4 +70,20 @@ public class AuthorizationAuditListenerTests { verify(this.publisher).publishEvent((ApplicationEvent) anyObject()); } + @Test + public void testDetailsAreIncludedInAuditEvent() throws Exception { + Object details = new Object(); + UsernamePasswordAuthenticationToken authentication = + new UsernamePasswordAuthenticationToken("user", "password"); + authentication.setDetails(details); + this.listener.onApplicationEvent(new AuthorizationFailureEvent(this, + Arrays.asList(new SecurityConfig("USER")), + authentication, new AccessDeniedException("Bad user"))); + ArgumentCaptor auditApplicationEvent = ArgumentCaptor + .forClass(AuditApplicationEvent.class); + verify(this.publisher).publishEvent(auditApplicationEvent.capture()); + assertThat(auditApplicationEvent.getValue().getAuditEvent().getData()) + .containsEntry("details", details); + } + }