|
|
|
@ -27,6 +27,7 @@ import org.springframework.context.ApplicationListener; |
|
|
|
import org.springframework.security.authentication.event.AbstractAuthenticationEvent; |
|
|
|
import org.springframework.security.authentication.event.AbstractAuthenticationEvent; |
|
|
|
import org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent; |
|
|
|
import org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent; |
|
|
|
import org.springframework.security.web.authentication.switchuser.AuthenticationSwitchUserEvent; |
|
|
|
import org.springframework.security.web.authentication.switchuser.AuthenticationSwitchUserEvent; |
|
|
|
|
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* {@link ApplicationListener} expose Spring Security {@link AbstractAuthenticationEvent |
|
|
|
* {@link ApplicationListener} expose Spring Security {@link AbstractAuthenticationEvent |
|
|
|
@ -39,18 +40,30 @@ public class AuthenticationAuditListener implements |
|
|
|
|
|
|
|
|
|
|
|
private ApplicationEventPublisher publisher; |
|
|
|
private ApplicationEventPublisher publisher; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private WebAuditListener webListener = maybeCreateWebListener(); |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { |
|
|
|
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { |
|
|
|
this.publisher = publisher; |
|
|
|
this.publisher = publisher; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static WebAuditListener maybeCreateWebListener() { |
|
|
|
|
|
|
|
if (ClassUtils |
|
|
|
|
|
|
|
.isPresent( |
|
|
|
|
|
|
|
"org.springframework.security.web.authentication.switchuser.AuthenticationSwitchUserEvent", |
|
|
|
|
|
|
|
null)) { |
|
|
|
|
|
|
|
return new WebAuditListener(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void onApplicationEvent(AbstractAuthenticationEvent event) { |
|
|
|
public void onApplicationEvent(AbstractAuthenticationEvent event) { |
|
|
|
if (event instanceof AbstractAuthenticationFailureEvent) { |
|
|
|
if (event instanceof AbstractAuthenticationFailureEvent) { |
|
|
|
onAuthenticationFailureEvent((AbstractAuthenticationFailureEvent) event); |
|
|
|
onAuthenticationFailureEvent((AbstractAuthenticationFailureEvent) event); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (event instanceof AuthenticationSwitchUserEvent) { |
|
|
|
else if (this.webListener != null && this.webListener.accepts(event)) { |
|
|
|
onAuthenticationSwitchUserEvent((AuthenticationSwitchUserEvent) event); |
|
|
|
this.webListener.process(this, event); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
onAuthenticationEvent(event); |
|
|
|
onAuthenticationEvent(event); |
|
|
|
@ -65,29 +78,42 @@ public class AuthenticationAuditListener implements |
|
|
|
"AUTHENTICATION_FAILURE", data)); |
|
|
|
"AUTHENTICATION_FAILURE", data)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void onAuthenticationSwitchUserEvent(AuthenticationSwitchUserEvent event) { |
|
|
|
private void onAuthenticationEvent(AbstractAuthenticationEvent event) { |
|
|
|
Map<String, Object> data = new HashMap<String, Object>(); |
|
|
|
Map<String, Object> data = new HashMap<String, Object>(); |
|
|
|
if (event.getAuthentication().getDetails() != null) { |
|
|
|
if (event.getAuthentication().getDetails() != null) { |
|
|
|
data.put("details", event.getAuthentication().getDetails()); |
|
|
|
data.put("details", event.getAuthentication().getDetails()); |
|
|
|
} |
|
|
|
} |
|
|
|
data.put("target", event.getTargetUser().getUsername()); |
|
|
|
|
|
|
|
publish(new AuditEvent(event.getAuthentication().getName(), |
|
|
|
publish(new AuditEvent(event.getAuthentication().getName(), |
|
|
|
"AUTHENTICATION_SWITCH", data)); |
|
|
|
"AUTHENTICATION_SUCCESS", data)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void onAuthenticationEvent(AbstractAuthenticationEvent event) { |
|
|
|
private void publish(AuditEvent event) { |
|
|
|
|
|
|
|
if (this.publisher != null) { |
|
|
|
|
|
|
|
this.publisher.publishEvent(new AuditApplicationEvent(event)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static class WebAuditListener { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void process(AuthenticationAuditListener listener, |
|
|
|
|
|
|
|
AbstractAuthenticationEvent input) { |
|
|
|
|
|
|
|
if (listener != null) { |
|
|
|
|
|
|
|
AuthenticationSwitchUserEvent event = (AuthenticationSwitchUserEvent) input; |
|
|
|
Map<String, Object> data = new HashMap<String, Object>(); |
|
|
|
Map<String, Object> data = new HashMap<String, Object>(); |
|
|
|
if (event.getAuthentication().getDetails() != null) { |
|
|
|
if (event.getAuthentication().getDetails() != null) { |
|
|
|
data.put("details", event.getAuthentication().getDetails()); |
|
|
|
data.put("details", event.getAuthentication().getDetails()); |
|
|
|
} |
|
|
|
} |
|
|
|
publish(new AuditEvent(event.getAuthentication().getName(), |
|
|
|
data.put("target", event.getTargetUser().getUsername()); |
|
|
|
"AUTHENTICATION_SUCCESS", data)); |
|
|
|
listener.publish(new AuditEvent(event.getAuthentication().getName(), |
|
|
|
|
|
|
|
"AUTHENTICATION_SWITCH", data)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void publish(AuditEvent event) { |
|
|
|
|
|
|
|
if (this.publisher != null) { |
|
|
|
|
|
|
|
this.publisher.publishEvent(new AuditApplicationEvent(event)); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public boolean accepts(AbstractAuthenticationEvent event) { |
|
|
|
|
|
|
|
return event instanceof AuthenticationSwitchUserEvent; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|