Merge pull request #6852 from vpavic:enumerate-audit-event-types
* pr/6852: Polish contribution Add constants for supported audit event types
This commit is contained in:
commit
9e55752bdf
|
|
@ -30,9 +30,25 @@ import org.springframework.util.ClassUtils;
|
||||||
* Default implementation of {@link AbstractAuthenticationAuditListener}.
|
* Default implementation of {@link AbstractAuthenticationAuditListener}.
|
||||||
*
|
*
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
|
* @author Vedran Pavic
|
||||||
*/
|
*/
|
||||||
public class AuthenticationAuditListener extends AbstractAuthenticationAuditListener {
|
public class AuthenticationAuditListener extends AbstractAuthenticationAuditListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authentication success event type.
|
||||||
|
*/
|
||||||
|
public static final String AUTHENTICATION_SUCCESS = "AUTHENTICATION_SUCCESS";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authentication failure event type.
|
||||||
|
*/
|
||||||
|
public static final String AUTHENTICATION_FAILURE = "AUTHENTICATION_FAILURE";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authentication switch event type.
|
||||||
|
*/
|
||||||
|
public static final String AUTHENTICATION_SWITCH = "AUTHENTICATION_SWITCH";
|
||||||
|
|
||||||
private static final String WEB_LISTENER_CHECK_CLASS = "org.springframework.security.web.authentication.switchuser.AuthenticationSwitchUserEvent";
|
private static final String WEB_LISTENER_CHECK_CLASS = "org.springframework.security.web.authentication.switchuser.AuthenticationSwitchUserEvent";
|
||||||
|
|
||||||
private WebAuditListener webListener = maybeCreateWebListener();
|
private WebAuditListener webListener = maybeCreateWebListener();
|
||||||
|
|
@ -65,7 +81,7 @@ public class AuthenticationAuditListener extends AbstractAuthenticationAuditList
|
||||||
data.put("details", event.getAuthentication().getDetails());
|
data.put("details", event.getAuthentication().getDetails());
|
||||||
}
|
}
|
||||||
publish(new AuditEvent(event.getAuthentication().getName(),
|
publish(new AuditEvent(event.getAuthentication().getName(),
|
||||||
"AUTHENTICATION_FAILURE", data));
|
AUTHENTICATION_FAILURE, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onAuthenticationSuccessEvent(AuthenticationSuccessEvent event) {
|
private void onAuthenticationSuccessEvent(AuthenticationSuccessEvent event) {
|
||||||
|
|
@ -74,7 +90,7 @@ public class AuthenticationAuditListener extends AbstractAuthenticationAuditList
|
||||||
data.put("details", event.getAuthentication().getDetails());
|
data.put("details", event.getAuthentication().getDetails());
|
||||||
}
|
}
|
||||||
publish(new AuditEvent(event.getAuthentication().getName(),
|
publish(new AuditEvent(event.getAuthentication().getName(),
|
||||||
"AUTHENTICATION_SUCCESS", data));
|
AUTHENTICATION_SUCCESS, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class WebAuditListener {
|
private static class WebAuditListener {
|
||||||
|
|
@ -89,7 +105,7 @@ public class AuthenticationAuditListener extends AbstractAuthenticationAuditList
|
||||||
}
|
}
|
||||||
data.put("target", event.getTargetUser().getUsername());
|
data.put("target", event.getTargetUser().getUsername());
|
||||||
listener.publish(new AuditEvent(event.getAuthentication().getName(),
|
listener.publish(new AuditEvent(event.getAuthentication().getName(),
|
||||||
"AUTHENTICATION_SWITCH", data));
|
AUTHENTICATION_SWITCH, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,15 @@ import org.springframework.security.access.event.AuthorizationFailureEvent;
|
||||||
* Default implementation of {@link AbstractAuthorizationAuditListener}.
|
* Default implementation of {@link AbstractAuthorizationAuditListener}.
|
||||||
*
|
*
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
|
* @author Vedran Pavic
|
||||||
*/
|
*/
|
||||||
public class AuthorizationAuditListener extends AbstractAuthorizationAuditListener {
|
public class AuthorizationAuditListener extends AbstractAuthorizationAuditListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authorization failure event type.
|
||||||
|
*/
|
||||||
|
public static final String AUTHORIZATION_FAILURE = "AUTHORIZATION_FAILURE";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onApplicationEvent(AbstractAuthorizationEvent event) {
|
public void onApplicationEvent(AbstractAuthorizationEvent event) {
|
||||||
if (event instanceof AuthenticationCredentialsNotFoundEvent) {
|
if (event instanceof AuthenticationCredentialsNotFoundEvent) {
|
||||||
|
|
@ -47,7 +53,8 @@ public class AuthorizationAuditListener extends AbstractAuthorizationAuditListen
|
||||||
Map<String, Object> data = new HashMap<String, Object>();
|
Map<String, Object> data = new HashMap<String, Object>();
|
||||||
data.put("type", event.getCredentialsNotFoundException().getClass().getName());
|
data.put("type", event.getCredentialsNotFoundException().getClass().getName());
|
||||||
data.put("message", event.getCredentialsNotFoundException().getMessage());
|
data.put("message", event.getCredentialsNotFoundException().getMessage());
|
||||||
publish(new AuditEvent("<unknown>", "AUTHENTICATION_FAILURE", data));
|
publish(new AuditEvent("<unknown>",
|
||||||
|
AuthenticationAuditListener.AUTHENTICATION_FAILURE, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onAuthorizationFailureEvent(AuthorizationFailureEvent event) {
|
private void onAuthorizationFailureEvent(AuthorizationFailureEvent event) {
|
||||||
|
|
@ -58,7 +65,7 @@ public class AuthorizationAuditListener extends AbstractAuthorizationAuditListen
|
||||||
data.put("details", event.getAuthentication().getDetails());
|
data.put("details", event.getAuthentication().getDetails());
|
||||||
}
|
}
|
||||||
publish(new AuditEvent(event.getAuthentication().getName(),
|
publish(new AuditEvent(event.getAuthentication().getName(),
|
||||||
"AUTHORIZATION_FAILURE", data));
|
AUTHORIZATION_FAILURE, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import org.springframework.context.ApplicationEvent;
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.security.authentication.BadCredentialsException;
|
import org.springframework.security.authentication.BadCredentialsException;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.authentication.event.AbstractAuthenticationEvent;
|
||||||
import org.springframework.security.authentication.event.AuthenticationFailureExpiredEvent;
|
import org.springframework.security.authentication.event.AuthenticationFailureExpiredEvent;
|
||||||
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
|
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
|
||||||
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;
|
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;
|
||||||
|
|
@ -55,9 +56,11 @@ public class AuthenticationAuditListenerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationSuccess() {
|
public void testAuthenticationSuccess() {
|
||||||
this.listener.onApplicationEvent(new AuthenticationSuccessEvent(
|
AuditApplicationEvent event = handleAuthenticationEvent(
|
||||||
new UsernamePasswordAuthenticationToken("user", "password")));
|
new AuthenticationSuccessEvent(
|
||||||
verify(this.publisher).publishEvent((ApplicationEvent) anyObject());
|
new UsernamePasswordAuthenticationToken("user", "password")));
|
||||||
|
assertThat(event.getAuditEvent().getType())
|
||||||
|
.isEqualTo(AuthenticationAuditListener.AUTHENTICATION_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -70,19 +73,23 @@ public class AuthenticationAuditListenerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationFailed() {
|
public void testAuthenticationFailed() {
|
||||||
this.listener.onApplicationEvent(new AuthenticationFailureExpiredEvent(
|
AuditApplicationEvent event = handleAuthenticationEvent(
|
||||||
new UsernamePasswordAuthenticationToken("user", "password"),
|
new AuthenticationFailureExpiredEvent(
|
||||||
new BadCredentialsException("Bad user")));
|
new UsernamePasswordAuthenticationToken("user", "password"),
|
||||||
verify(this.publisher).publishEvent((ApplicationEvent) anyObject());
|
new BadCredentialsException("Bad user")));
|
||||||
|
assertThat(event.getAuditEvent().getType())
|
||||||
|
.isEqualTo(AuthenticationAuditListener.AUTHENTICATION_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationSwitch() {
|
public void testAuthenticationSwitch() {
|
||||||
this.listener.onApplicationEvent(new AuthenticationSwitchUserEvent(
|
AuditApplicationEvent event = handleAuthenticationEvent(
|
||||||
new UsernamePasswordAuthenticationToken("user", "password"),
|
new AuthenticationSwitchUserEvent(
|
||||||
new User("user", "password",
|
new UsernamePasswordAuthenticationToken("user", "password"),
|
||||||
AuthorityUtils.commaSeparatedStringToAuthorityList("USER"))));
|
new User("user", "password",
|
||||||
verify(this.publisher).publishEvent((ApplicationEvent) anyObject());
|
AuthorityUtils.commaSeparatedStringToAuthorityList("USER"))));
|
||||||
|
assertThat(event.getAuditEvent().getType())
|
||||||
|
.isEqualTo(AuthenticationAuditListener.AUTHENTICATION_SWITCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -91,13 +98,21 @@ public class AuthenticationAuditListenerTests {
|
||||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
|
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
|
||||||
"user", "password");
|
"user", "password");
|
||||||
authentication.setDetails(details);
|
authentication.setDetails(details);
|
||||||
this.listener.onApplicationEvent(new AuthenticationFailureExpiredEvent(
|
AuditApplicationEvent event = handleAuthenticationEvent(new AuthenticationFailureExpiredEvent(
|
||||||
authentication, new BadCredentialsException("Bad user")));
|
authentication, new BadCredentialsException("Bad user")));
|
||||||
ArgumentCaptor<AuditApplicationEvent> auditApplicationEvent = ArgumentCaptor
|
assertThat(event.getAuditEvent().getType())
|
||||||
.forClass(AuditApplicationEvent.class);
|
.isEqualTo(AuthenticationAuditListener.AUTHENTICATION_FAILURE);
|
||||||
verify(this.publisher).publishEvent(auditApplicationEvent.capture());
|
assertThat(event.getAuditEvent().getData())
|
||||||
assertThat(auditApplicationEvent.getValue().getAuditEvent().getData())
|
|
||||||
.containsEntry("details", details);
|
.containsEntry("details", details);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AuditApplicationEvent handleAuthenticationEvent(
|
||||||
|
AbstractAuthenticationEvent event) {
|
||||||
|
ArgumentCaptor<AuditApplicationEvent> eventCaptor = ArgumentCaptor
|
||||||
|
.forClass(AuditApplicationEvent.class);
|
||||||
|
this.listener.onApplicationEvent(event);
|
||||||
|
verify(this.publisher).publishEvent(eventCaptor.capture());
|
||||||
|
return eventCaptor.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,25 +16,24 @@
|
||||||
|
|
||||||
package org.springframework.boot.actuate.security;
|
package org.springframework.boot.actuate.security;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Collections;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.audit.listener.AuditApplicationEvent;
|
import org.springframework.boot.actuate.audit.listener.AuditApplicationEvent;
|
||||||
import org.springframework.context.ApplicationEvent;
|
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.security.access.AccessDeniedException;
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
import org.springframework.security.access.ConfigAttribute;
|
import org.springframework.security.access.ConfigAttribute;
|
||||||
import org.springframework.security.access.SecurityConfig;
|
import org.springframework.security.access.SecurityConfig;
|
||||||
|
import org.springframework.security.access.event.AbstractAuthorizationEvent;
|
||||||
import org.springframework.security.access.event.AuthenticationCredentialsNotFoundEvent;
|
import org.springframework.security.access.event.AuthenticationCredentialsNotFoundEvent;
|
||||||
import org.springframework.security.access.event.AuthorizationFailureEvent;
|
import org.springframework.security.access.event.AuthorizationFailureEvent;
|
||||||
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
|
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.Matchers.anyObject;
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
|
@ -55,19 +54,23 @@ public class AuthorizationAuditListenerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationCredentialsNotFound() {
|
public void testAuthenticationCredentialsNotFound() {
|
||||||
this.listener.onApplicationEvent(new AuthenticationCredentialsNotFoundEvent(this,
|
AuditApplicationEvent event = handleAuthorizationEvent(
|
||||||
Arrays.<ConfigAttribute>asList(new SecurityConfig("USER")),
|
new AuthenticationCredentialsNotFoundEvent(this,
|
||||||
new AuthenticationCredentialsNotFoundException("Bad user")));
|
Collections.<ConfigAttribute>singletonList(new SecurityConfig("USER")),
|
||||||
verify(this.publisher).publishEvent((ApplicationEvent) anyObject());
|
new AuthenticationCredentialsNotFoundException("Bad user")));
|
||||||
|
assertThat(event.getAuditEvent().getType())
|
||||||
|
.isEqualTo(AuthenticationAuditListener.AUTHENTICATION_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthorizationFailure() {
|
public void testAuthorizationFailure() {
|
||||||
this.listener.onApplicationEvent(new AuthorizationFailureEvent(this,
|
AuditApplicationEvent event = handleAuthorizationEvent(
|
||||||
Arrays.<ConfigAttribute>asList(new SecurityConfig("USER")),
|
new AuthorizationFailureEvent(this,
|
||||||
new UsernamePasswordAuthenticationToken("user", "password"),
|
Collections.<ConfigAttribute>singletonList(new SecurityConfig("USER")),
|
||||||
new AccessDeniedException("Bad user")));
|
new UsernamePasswordAuthenticationToken("user", "password"),
|
||||||
verify(this.publisher).publishEvent((ApplicationEvent) anyObject());
|
new AccessDeniedException("Bad user")));
|
||||||
|
assertThat(event.getAuditEvent().getType())
|
||||||
|
.isEqualTo(AuthorizationAuditListener.AUTHORIZATION_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -76,14 +79,22 @@ public class AuthorizationAuditListenerTests {
|
||||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
|
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
|
||||||
"user", "password");
|
"user", "password");
|
||||||
authentication.setDetails(details);
|
authentication.setDetails(details);
|
||||||
this.listener.onApplicationEvent(new AuthorizationFailureEvent(this,
|
AuditApplicationEvent event = handleAuthorizationEvent(
|
||||||
Arrays.<ConfigAttribute>asList(new SecurityConfig("USER")),
|
new AuthorizationFailureEvent(this,
|
||||||
authentication, new AccessDeniedException("Bad user")));
|
Collections.<ConfigAttribute>singletonList(new SecurityConfig("USER")),
|
||||||
ArgumentCaptor<AuditApplicationEvent> auditApplicationEvent = ArgumentCaptor
|
authentication, new AccessDeniedException("Bad user")));
|
||||||
|
assertThat(event.getAuditEvent().getType())
|
||||||
|
.isEqualTo(AuthorizationAuditListener.AUTHORIZATION_FAILURE);
|
||||||
|
assertThat(event.getAuditEvent().getData()).containsEntry("details", details);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AuditApplicationEvent handleAuthorizationEvent(
|
||||||
|
AbstractAuthorizationEvent event) {
|
||||||
|
ArgumentCaptor<AuditApplicationEvent> eventCaptor = ArgumentCaptor
|
||||||
.forClass(AuditApplicationEvent.class);
|
.forClass(AuditApplicationEvent.class);
|
||||||
verify(this.publisher).publishEvent(auditApplicationEvent.capture());
|
this.listener.onApplicationEvent(event);
|
||||||
assertThat(auditApplicationEvent.getValue().getAuditEvent().getData())
|
verify(this.publisher).publishEvent(eventCaptor.capture());
|
||||||
.containsEntry("details", details);
|
return eventCaptor.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue