From c5953feae68f60918205cd9c78d428a0344505aa Mon Sep 17 00:00:00 2001 From: chu3la Date: Sun, 30 Jun 2024 12:08:37 +0100 Subject: [PATCH 1/2] Publish an AuditEvent on logout See gh-41278 --- .../security/AuthenticationAuditListener.java | 21 +++++++++++++++++++ .../AuthenticationAuditListenerTests.java | 8 +++++++ 2 files changed, 29 insertions(+) diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthenticationAuditListener.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthenticationAuditListener.java index f35bd90593..a7e1e87725 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthenticationAuditListener.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthenticationAuditListener.java @@ -24,6 +24,7 @@ import org.springframework.boot.actuate.audit.AuditEvent; import org.springframework.security.authentication.event.AbstractAuthenticationEvent; import org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent; import org.springframework.security.authentication.event.AuthenticationSuccessEvent; +import org.springframework.security.authentication.event.LogoutSuccessEvent; import org.springframework.security.web.authentication.switchuser.AuthenticationSwitchUserEvent; import org.springframework.util.ClassUtils; @@ -51,6 +52,14 @@ public class AuthenticationAuditListener extends AbstractAuthenticationAuditList */ public static final String AUTHENTICATION_SWITCH = "AUTHENTICATION_SWITCH"; + /** + * This constant is used to indicate that the logout process + * has been completed successfully. + * + * @since 3.4.0 + */ + public static final String LOGOUT_SUCCESS = "LOGOUT_SUCCESS"; + private static final String WEB_LISTENER_CHECK_CLASS = "org.springframework.security.web.authentication.switchuser.AuthenticationSwitchUserEvent"; private final WebAuditListener webListener = maybeCreateWebListener(); @@ -73,6 +82,9 @@ public class AuthenticationAuditListener extends AbstractAuthenticationAuditList else if (event instanceof AuthenticationSuccessEvent successEvent) { onAuthenticationSuccessEvent(successEvent); } + else if (event instanceof LogoutSuccessEvent logoutSuccessEvent) { + onLogoutSuccessEvent(logoutSuccessEvent); + } } private void onAuthenticationFailureEvent(AbstractAuthenticationFailureEvent event) { @@ -93,6 +105,15 @@ public class AuthenticationAuditListener extends AbstractAuthenticationAuditList publish(new AuditEvent(event.getAuthentication().getName(), AUTHENTICATION_SUCCESS, data)); } + private void onLogoutSuccessEvent(LogoutSuccessEvent event) { + Map data = new LinkedHashMap<>(); + if (event.getAuthentication().getDetails() != null) { + data.put("details", event.getAuthentication().getDetails()); + } + publish(new AuditEvent(event.getAuthentication().getName(), LOGOUT_SUCCESS, data)); + + } + private static final class WebAuditListener { void process(AuthenticationAuditListener listener, AbstractAuthenticationEvent input) { diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/security/AuthenticationAuditListenerTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/security/AuthenticationAuditListenerTests.java index 77f973c656..04d22ab9ad 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/security/AuthenticationAuditListenerTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/security/AuthenticationAuditListenerTests.java @@ -29,6 +29,7 @@ import org.springframework.security.authentication.event.AbstractAuthenticationE import org.springframework.security.authentication.event.AuthenticationFailureExpiredEvent; import org.springframework.security.authentication.event.AuthenticationSuccessEvent; import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent; +import org.springframework.security.authentication.event.LogoutSuccessEvent; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.userdetails.User; import org.springframework.security.web.authentication.switchuser.AuthenticationSwitchUserEvent; @@ -60,6 +61,13 @@ class AuthenticationAuditListenerTests { assertThat(event.getAuditEvent().getType()).isEqualTo(AuthenticationAuditListener.AUTHENTICATION_SUCCESS); } + @Test + void testLogoutSucess() { + AuditApplicationEvent event = handleAuthenticationEvent( + new LogoutSuccessEvent(new UsernamePasswordAuthenticationToken("user", "password"))); + assertThat(event.getAuditEvent().getType()).isEqualTo(AuthenticationAuditListener.LOGOUT_SUCCESS); + } + @Test void testOtherAuthenticationSuccess() { this.listener.onApplicationEvent(new InteractiveAuthenticationSuccessEvent( From 0ce3420fcb6f868d967763e0f53dde68a36dce0b Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Wed, 3 Jul 2024 10:40:59 +0200 Subject: [PATCH 2/2] Polish "Publish an AuditEvent on logout" See gh-41278 --- .../boot/actuate/security/AuthenticationAuditListener.java | 4 +--- .../actuate/security/AuthenticationAuditListenerTests.java | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthenticationAuditListener.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthenticationAuditListener.java index a7e1e87725..13beb48e30 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthenticationAuditListener.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/security/AuthenticationAuditListener.java @@ -53,8 +53,7 @@ public class AuthenticationAuditListener extends AbstractAuthenticationAuditList public static final String AUTHENTICATION_SWITCH = "AUTHENTICATION_SWITCH"; /** - * This constant is used to indicate that the logout process - * has been completed successfully. + * Logout success event type. * * @since 3.4.0 */ @@ -111,7 +110,6 @@ public class AuthenticationAuditListener extends AbstractAuthenticationAuditList data.put("details", event.getAuthentication().getDetails()); } publish(new AuditEvent(event.getAuthentication().getName(), LOGOUT_SUCCESS, data)); - } private static final class WebAuditListener { diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/security/AuthenticationAuditListenerTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/security/AuthenticationAuditListenerTests.java index 04d22ab9ad..2b68d1dfd8 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/security/AuthenticationAuditListenerTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/security/AuthenticationAuditListenerTests.java @@ -62,7 +62,7 @@ class AuthenticationAuditListenerTests { } @Test - void testLogoutSucess() { + void testLogoutSuccess() { AuditApplicationEvent event = handleAuthenticationEvent( new LogoutSuccessEvent(new UsernamePasswordAuthenticationToken("user", "password"))); assertThat(event.getAuditEvent().getType()).isEqualTo(AuthenticationAuditListener.LOGOUT_SUCCESS);