Skip to content

Publish an AuditEvent on logout #41278

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add some javadoc here that describes the constant. It should also be marked with @since 3.4.0.


private static final String WEB_LISTENER_CHECK_CLASS = "org.springframework.security.web.authentication.switchuser.AuthenticationSwitchUserEvent";

private final WebAuditListener webListener = maybeCreateWebListener();
Expand All @@ -73,6 +82,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) {
Expand All @@ -93,6 +105,15 @@ private void onAuthenticationSuccessEvent(AuthenticationSuccessEvent event) {
publish(new AuditEvent(event.getAuthentication().getName(), AUTHENTICATION_SUCCESS, data));
}

private void onLogoutSuccessEvent(LogoutSuccessEvent event) {
Map<String, Object> 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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(
Expand Down