Add MVC and JMX endpoints to retrieve audit events

Add MVC and JMX specific endpoints that allow audit events to be
retrieved.

See gh-6579
This commit is contained in:
Vedran Pavic
2016-11-20 17:05:21 +01:00
committed by Phillip Webb
parent a6d18f714f
commit 2f1e4f0c02
28 changed files with 459 additions and 30 deletions

View File

@@ -103,7 +103,7 @@ public class EndpointMvcIntegrationTests {
@MinimalWebConfiguration
@Import({ ManagementServerPropertiesAutoConfiguration.class,
JacksonAutoConfiguration.class, EndpointAutoConfiguration.class,
EndpointWebMvcAutoConfiguration.class })
EndpointWebMvcAutoConfiguration.class, AuditAutoConfiguration.class })
@RestController
protected static class Application {

View File

@@ -364,7 +364,7 @@ public class EndpointWebMvcAutoConfigurationTests {
EmbeddedServletContainerAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class,
EndpointWebMvcAutoConfiguration.class);
EndpointWebMvcAutoConfiguration.class, AuditAutoConfiguration.class);
this.applicationContext.refresh();
assertContent("/controller", ports.get().server, "controlleroutput");
assertContent("/test/endpoint", ports.get().server, "endpointoutput");
@@ -381,7 +381,7 @@ public class EndpointWebMvcAutoConfigurationTests {
EmbeddedServletContainerAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class,
EndpointWebMvcAutoConfiguration.class);
EndpointWebMvcAutoConfiguration.class, AuditAutoConfiguration.class);
this.applicationContext.refresh();
assertContent("/controller", ports.get().server, "controlleroutput");
ServerProperties serverProperties = this.applicationContext
@@ -440,9 +440,9 @@ public class EndpointWebMvcAutoConfigurationTests {
BaseConfiguration.class, ServerPortConfig.class,
EndpointWebMvcAutoConfiguration.class);
this.applicationContext.refresh();
// /health, /metrics, /loggers, /env, /actuator, /heapdump (/shutdown is disabled
// by default)
assertThat(this.applicationContext.getBeansOfType(MvcEndpoint.class)).hasSize(6);
// /health, /metrics, /loggers, /env, /actuator, /heapdump, /auditevents
// (/shutdown is disabled by default)
assertThat(this.applicationContext.getBeansOfType(MvcEndpoint.class)).hasSize(7);
}
@Test
@@ -734,7 +734,7 @@ public class EndpointWebMvcAutoConfigurationTests {
HttpMessageConvertersAutoConfiguration.class,
DispatcherServletAutoConfiguration.class, WebMvcAutoConfiguration.class,
ManagementServerPropertiesAutoConfiguration.class,
ServerPropertiesAutoConfiguration.class })
ServerPropertiesAutoConfiguration.class, AuditAutoConfiguration.class })
protected static class BaseConfiguration {
}

View File

@@ -84,7 +84,7 @@ public class HealthMvcEndpointAutoConfigurationTests {
@Configuration
@ImportAutoConfiguration({ SecurityAutoConfiguration.class,
JacksonAutoConfiguration.class, WebMvcAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class, AuditAutoConfiguration.class,
ManagementServerPropertiesAutoConfiguration.class,
EndpointAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class })
static class TestConfiguration {

View File

@@ -91,7 +91,7 @@ public class ManagementWebSecurityAutoConfigurationTests {
HttpMessageConvertersAutoConfiguration.class,
EndpointAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class,
ManagementServerPropertiesAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
PropertyPlaceholderAutoConfiguration.class, AuditAutoConfiguration.class);
EnvironmentTestUtils.addEnvironment(this.context, "security.basic.enabled:false");
this.context.refresh();
assertThat(this.context.getBean(AuthenticationManagerBuilder.class)).isNotNull();
@@ -203,7 +203,7 @@ public class ManagementWebSecurityAutoConfigurationTests {
EndpointAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class,
ManagementServerPropertiesAutoConfiguration.class,
WebMvcAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
PropertyPlaceholderAutoConfiguration.class, AuditAutoConfiguration.class);
this.context.refresh();
Filter filter = this.context.getBean("springSecurityFilterChain", Filter.class);
@@ -265,7 +265,7 @@ public class ManagementWebSecurityAutoConfigurationTests {
JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class,
EndpointAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class,
ManagementServerPropertiesAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class, AuditAutoConfiguration.class,
FallbackWebSecurityAutoConfiguration.class })
static class WebConfiguration {

View File

@@ -51,7 +51,7 @@ import org.springframework.context.annotation.Configuration;
HttpMessageConvertersAutoConfiguration.class, WebMvcAutoConfiguration.class,
HypermediaAutoConfiguration.class, EndpointAutoConfiguration.class,
EndpointWebMvcAutoConfiguration.class, ErrorMvcAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class })
PropertyPlaceholderAutoConfiguration.class, AuditAutoConfiguration.class })
public @interface MinimalActuatorHypermediaApplication {
}

View File

@@ -35,6 +35,7 @@ import org.springframework.boot.actuate.endpoint.LiquibaseEndpoint;
import org.springframework.boot.actuate.endpoint.RequestMappingEndpoint;
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
import org.springframework.boot.actuate.endpoint.TraceEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.AuditEventsMvcEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.DocsMvcEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter;
import org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint;
@@ -85,6 +86,7 @@ public class MvcEndpointPathConfigurationTests {
@Parameters(name = "{0}")
public static Object[] parameters() {
return new Object[] { new Object[] { "actuator", HalJsonMvcEndpoint.class },
new Object[] { "auditevents", AuditEventsMvcEndpoint.class },
new Object[] { "autoconfig", AutoConfigurationReportEndpoint.class },
new Object[] { "beans", BeansEndpoint.class },
new Object[] { "configprops",
@@ -143,9 +145,8 @@ public class MvcEndpointPathConfigurationTests {
@ImportAutoConfiguration({ EndpointAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
ManagementServerPropertiesAutoConfiguration.class,
ServerPropertiesAutoConfiguration.class,
EndpointWebMvcAutoConfiguration.class, JolokiaAutoConfiguration.class,
EndpointAutoConfiguration.class })
ServerPropertiesAutoConfiguration.class, AuditAutoConfiguration.class,
EndpointWebMvcAutoConfiguration.class, JolokiaAutoConfiguration.class })
protected static class TestConfiguration {

View File

@@ -0,0 +1,125 @@
/*
* Copyright 2012-2016 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.endpoint.mvc;
import java.time.Instant;
import java.util.Collections;
import java.util.Date;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.audit.AuditEvent;
import org.springframework.boot.actuate.audit.AuditEventRepository;
import org.springframework.boot.actuate.audit.InMemoryAuditEventRepository;
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration;
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link AuditEventsMvcEndpoint}.
*
* @author Vedran Pavic
*/
@SpringBootTest
@RunWith(SpringRunner.class)
public class AuditEventsMvcEndpointTests {
@Autowired
private WebApplicationContext context;
private MockMvc mvc;
@Before
public void setUp() {
this.context.getBean(AuditEventsMvcEndpoint.class).setEnabled(true);
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
}
@Test
public void invokeWhenDisabledShouldReturnNotFoundStatus() throws Exception {
this.context.getBean(AuditEventsMvcEndpoint.class).setEnabled(false);
this.mvc.perform(get("/auditevents").param("after", "2016-11-01T10:00:00+0000"))
.andExpect(status().isNotFound());
}
@Test
public void invokeFilterByDateAfter() throws Exception {
this.mvc.perform(get("/auditevents").param("after", "2016-11-01T13:00:00+0000"))
.andExpect(status().isOk()).andExpect(content().string("[]"));
}
@Test
public void invokeFilterByPrincipalAndDateAfter() throws Exception {
this.mvc.perform(get("/auditevents").param("principal", "user")
.param("after", "2016-11-01T10:00:00+0000"))
.andExpect(status().isOk())
.andExpect(content().string(containsString(
"\"principal\":\"user\",\"type\":\"login\"")))
.andExpect(content().string(not(containsString("admin"))));
}
@Test
public void invokeFilterByPrincipalAndDateAfterAndType() throws Exception {
this.mvc.perform(get("/auditevents").param("principal", "admin")
.param("after", "2016-11-01T10:00:00+0000")
.param("type", "logout")).andExpect(status().isOk())
.andExpect(content().string(containsString(
"\"principal\":\"admin\",\"type\":\"logout\"")))
.andExpect(content().string(not(containsString("login"))));
}
@Import({ JacksonAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
EndpointWebMvcAutoConfiguration.class, WebMvcAutoConfiguration.class,
ManagementServerPropertiesAutoConfiguration.class })
@Configuration
protected static class TestConfiguration {
@Bean
public AuditEventRepository auditEventsRepository() {
AuditEventRepository repository = new InMemoryAuditEventRepository(3);
repository.add(new AuditEvent(Date.from(Instant.parse(
"2016-11-01T11:00:00Z")), "admin", "login", Collections.emptyMap()));
repository.add(new AuditEvent(Date.from(Instant.parse(
"2016-11-01T12:00:00Z")), "admin", "logout", Collections.emptyMap()));
repository.add(new AuditEvent(Date.from(Instant.parse(
"2016-11-01T12:00:00Z")), "user", "login", Collections.emptyMap()));
return repository;
}
}
}

View File

@@ -24,6 +24,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
import org.springframework.boot.actuate.endpoint.EnvironmentEndpoint;
@@ -107,7 +108,7 @@ public class EnvironmentMvcEndpointTests {
@Configuration
@Import({ JacksonAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class, WebMvcAutoConfiguration.class,
EndpointWebMvcAutoConfiguration.class,
EndpointWebMvcAutoConfiguration.class, AuditAutoConfiguration.class,
ManagementServerPropertiesAutoConfiguration.class })
public static class TestConfiguration {

View File

@@ -31,6 +31,7 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@@ -86,7 +87,11 @@ public class HalBrowserMvcEndpointDisabledIntegrationTests {
continue;
}
path = path.length() > 0 ? path : "/";
this.mockMvc.perform(get(path).accept(MediaType.APPLICATION_JSON))
MockHttpServletRequestBuilder requestBuilder = get(path);
if (endpoint instanceof AuditEventsMvcEndpoint) {
requestBuilder.param("after", "2016-01-01T12:00:00+00:00");
}
this.mockMvc.perform(requestBuilder.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$._links").doesNotExist());
}

View File

@@ -119,8 +119,8 @@ public class HalBrowserMvcEndpointVanillaIntegrationTests {
@Test
public void endpointsEachHaveSelf() throws Exception {
Set<String> collections = new HashSet<String>(
Arrays.asList("/trace", "/beans", "/dump", "/heapdump", "/loggers"));
Set<String> collections = new HashSet<String>(Arrays.asList("/trace", "/beans",
"/dump", "/heapdump", "/loggers", "/auditevents"));
for (MvcEndpoint endpoint : this.mvcEndpoints.getEndpoints()) {
String path = endpoint.getPath();
if (collections.contains(path)) {

View File

@@ -28,6 +28,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
@@ -114,7 +115,7 @@ public class HeapdumpMvcEndpointTests {
this.mvc.perform(options("/heapdump")).andExpect(status().isOk());
}
@Import({ JacksonAutoConfiguration.class,
@Import({ JacksonAutoConfiguration.class, AuditAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
EndpointWebMvcAutoConfiguration.class, WebMvcAutoConfiguration.class,
ManagementServerPropertiesAutoConfiguration.class })

View File

@@ -25,6 +25,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
import org.springframework.boot.actuate.endpoint.InfoEndpoint;
@@ -79,7 +80,7 @@ public class InfoMvcEndpointTests {
"\"beanName2\":{\"key21\":\"value21\",\"key22\":\"value22\"}")));
}
@Import({ JacksonAutoConfiguration.class,
@Import({ JacksonAutoConfiguration.class, AuditAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
EndpointWebMvcAutoConfiguration.class, WebMvcAutoConfiguration.class,
ManagementServerPropertiesAutoConfiguration.class })

View File

@@ -23,6 +23,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
import org.springframework.boot.actuate.endpoint.InfoEndpoint;
@@ -68,7 +69,7 @@ public class InfoMvcEndpointWithNoInfoContributorsTests {
this.mvc.perform(get("/info")).andExpect(status().isOk());
}
@Import({ JacksonAutoConfiguration.class,
@Import({ JacksonAutoConfiguration.class, AuditAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
EndpointWebMvcAutoConfiguration.class, WebMvcAutoConfiguration.class,
ManagementServerPropertiesAutoConfiguration.class })

View File

@@ -21,6 +21,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.JolokiaAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
@@ -85,7 +86,7 @@ public class JolokiaMvcEndpointContextPathTests {
@Configuration
@EnableConfigurationProperties
@EnableWebMvc
@Import({ JacksonAutoConfiguration.class,
@Import({ JacksonAutoConfiguration.class, AuditAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
EndpointWebMvcAutoConfiguration.class, JolokiaAutoConfiguration.class,
ManagementServerPropertiesAutoConfiguration.class })

View File

@@ -23,6 +23,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.JolokiaAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
@@ -100,7 +101,7 @@ public class JolokiaMvcEndpointIntegrationTests {
@Configuration
@EnableConfigurationProperties
@EnableWebMvc
@Import({ JacksonAutoConfiguration.class,
@Import({ JacksonAutoConfiguration.class, AuditAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
EndpointWebMvcAutoConfiguration.class, JolokiaAutoConfiguration.class,
ManagementServerPropertiesAutoConfiguration.class })

View File

@@ -25,6 +25,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
import org.springframework.boot.actuate.endpoint.MetricsEndpoint;
@@ -129,7 +130,7 @@ public class MetricsMvcEndpointTests {
.andExpect(content().string(containsString("1")));
}
@Import({ JacksonAutoConfiguration.class,
@Import({ JacksonAutoConfiguration.class, AuditAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
EndpointWebMvcAutoConfiguration.class, WebMvcAutoConfiguration.class,
ManagementServerPropertiesAutoConfiguration.class })

View File

@@ -19,6 +19,7 @@ package org.springframework.boot.actuate.endpoint.mvc;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.JolokiaAutoConfiguration;
@@ -56,7 +57,7 @@ public class MvcEndpointCorsIntegrationTests {
HttpMessageConvertersAutoConfiguration.class,
EndpointAutoConfiguration.class, EndpointWebMvcAutoConfiguration.class,
ManagementServerPropertiesAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class, AuditAutoConfiguration.class,
JolokiaAutoConfiguration.class, WebMvcAutoConfiguration.class);
}

View File

@@ -19,6 +19,7 @@ package org.springframework.boot.actuate.endpoint.mvc;
import org.junit.After;
import org.junit.Test;
import org.springframework.boot.actuate.autoconfigure.AuditAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration;
@@ -229,9 +230,10 @@ public class MvcEndpointIntegrationTests {
@ImportAutoConfiguration({ JacksonAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class, EndpointAutoConfiguration.class,
EndpointWebMvcAutoConfiguration.class,
EndpointWebMvcAutoConfiguration.class, AuditAutoConfiguration.class,
ManagementServerPropertiesAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class, WebMvcAutoConfiguration.class })
PropertyPlaceholderAutoConfiguration.class, WebMvcAutoConfiguration.class,
AuditAutoConfiguration.class })
static class DefaultConfiguration {
}