From 8e6b4629d4e9f204ad8526617c5a345fe3c3ba71 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 12 Feb 2019 16:21:53 +0000 Subject: [PATCH] Tolerate AuthenticationSwitchUserEvent with null target user When Spring Security is misconfigured it's possible to switch from an anonymous user to a normal user. When switching back again, the corresponding AuthenticationSwitchUserEvent will have a null target user. Previously, Actuator's AuthenticationAuditListener would throw a NullPointerException when it received such an event. This commit updates the audit listener to defensively handled events with a null target user. Closes gh-15767 --- .../security/AuthenticationAuditListener.java | 6 ++++-- .../security/AuthenticationAuditListenerTests.java | 12 +++++++++++- 2 files changed, 15 insertions(+), 3 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 328ef924160..971a67a2bf0 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2019 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. @@ -103,7 +103,9 @@ public class AuthenticationAuditListener extends AbstractAuthenticationAuditList if (event.getAuthentication().getDetails() != null) { data.put("details", event.getAuthentication().getDetails()); } - data.put("target", event.getTargetUser().getUsername()); + if (event.getTargetUser() != null) { + data.put("target", event.getTargetUser().getUsername()); + } listener.publish(new AuditEvent(event.getAuthentication().getName(), AUTHENTICATION_SWITCH, data)); } 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 58bffa8baf8..39cdcd9a304 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 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. @@ -92,6 +92,16 @@ public class AuthenticationAuditListenerTests { .isEqualTo(AuthenticationAuditListener.AUTHENTICATION_SWITCH); } + @Test + public void testAuthenticationSwitchBackToAnonymous() { + AuditApplicationEvent event = handleAuthenticationEvent( + new AuthenticationSwitchUserEvent( + new UsernamePasswordAuthenticationToken("user", "password"), + null)); + assertThat(event.getAuditEvent().getType()) + .isEqualTo(AuthenticationAuditListener.AUTHENTICATION_SWITCH); + } + @Test public void testDetailsAreIncludedInAuditEvent() { Object details = new Object();