From b276a6c3a0b6052327b950e1e45831c96509647a 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 --- .../security/AuthenticationAuditListener.java | 18 ++++++++++++++++++ .../AuthenticationAuditListenerTests.java | 8 ++++++++ 2 files changed, 26 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 f35bd905935a..5199d3f94242 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.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,8 @@ public class AuthenticationAuditListener extends AbstractAuthenticationAuditList */ public static final String AUTHENTICATION_SWITCH = "AUTHENTICATION_SWITCH"; + 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 +76,9 @@ else if (this.webListener != null && this.webListener.accepts(event)) { else if (event instanceof AuthenticationSuccessEvent successEvent) { onAuthenticationSuccessEvent(successEvent); } + else if(event instanceof LogoutSuccessEvent logoutSuccessEvent) { + onLogoutSuccessEvent(logoutSuccessEvent); + } } private void onAuthenticationFailureEvent(AbstractAuthenticationFailureEvent event) { @@ -93,6 +99,18 @@ private void onAuthenticationSuccessEvent(AuthenticationSuccessEvent event) { publish(new AuditEvent(event.getAuthentication().getName(), AUTHENTICATION_SUCCESS, data)); } + private void onLogoutSuccessEvent(LogoutSuccessEvent event) { + Map data = new LinkedHashMap<>(); + if(event.getAuthentication() != null) { + if(event.getAuthentication().getDetails() != null) { + data.put("details", event.getAuthentication().getDetails()); + } + data.put("username", event.getAuthentication().getName()); + } + 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 77f973c65649..04d22ab9ad51 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.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 @@ void testAuthenticationSuccess() { 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 f9f4ffb615505c367a4febb28cc7c5f0b190b616 Mon Sep 17 00:00:00 2001 From: chu3la Date: Mon, 1 Jul 2024 17:09:42 +0100 Subject: [PATCH 2/2] Corrections added --- .../security/AuthenticationAuditListener.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 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 5199d3f94242..a7e1e87725fa 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 @@ -52,6 +52,12 @@ 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"; @@ -76,7 +82,7 @@ else if (this.webListener != null && this.webListener.accepts(event)) { else if (event instanceof AuthenticationSuccessEvent successEvent) { onAuthenticationSuccessEvent(successEvent); } - else if(event instanceof LogoutSuccessEvent logoutSuccessEvent) { + else if (event instanceof LogoutSuccessEvent logoutSuccessEvent) { onLogoutSuccessEvent(logoutSuccessEvent); } } @@ -101,11 +107,8 @@ private void onAuthenticationSuccessEvent(AuthenticationSuccessEvent event) { private void onLogoutSuccessEvent(LogoutSuccessEvent event) { Map data = new LinkedHashMap<>(); - if(event.getAuthentication() != null) { - if(event.getAuthentication().getDetails() != null) { - data.put("details", event.getAuthentication().getDetails()); - } - data.put("username", event.getAuthentication().getName()); + if (event.getAuthentication().getDetails() != null) { + data.put("details", event.getAuthentication().getDetails()); } publish(new AuditEvent(event.getAuthentication().getName(), LOGOUT_SUCCESS, data));