diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcManagementContextConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcManagementContextConfiguration.java index 2c95a5a229..d58fdc0cb7 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcManagementContextConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcManagementContextConfiguration.java @@ -20,7 +20,6 @@ import java.util.List; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.ManagementServerProperties.Security; import org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint; import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.boot.actuate.endpoint.EnvironmentEndpoint; @@ -51,6 +50,7 @@ import org.springframework.context.annotation.ConditionContext; import org.springframework.context.annotation.Conditional; import org.springframework.core.env.Environment; import org.springframework.core.type.AnnotatedTypeMetadata; +import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import org.springframework.web.cors.CorsConfiguration; @@ -143,9 +143,8 @@ public class EndpointWebMvcManagementContextConfiguration { @ConditionalOnBean(HealthEndpoint.class) @ConditionalOnEnabledEndpoint("health") public HealthMvcEndpoint healthMvcEndpoint(HealthEndpoint delegate) { - Security security = this.managementServerProperties.getSecurity(); - boolean secure = (security != null && security.isEnabled()); - HealthMvcEndpoint healthMvcEndpoint = new HealthMvcEndpoint(delegate, secure); + HealthMvcEndpoint healthMvcEndpoint = new HealthMvcEndpoint(delegate, + isHealthSecure()); if (this.healthMvcEndpointProperties.getMapping() != null) { healthMvcEndpoint .addStatusMapping(this.healthMvcEndpointProperties.getMapping()); @@ -181,6 +180,17 @@ public class EndpointWebMvcManagementContextConfiguration { return new ShutdownMvcEndpoint(delegate); } + private boolean isHealthSecure() { + return isSpringSecurityAvailable() + && this.managementServerProperties.getSecurity().isEnabled(); + } + + private boolean isSpringSecurityAvailable() { + return ClassUtils.isPresent( + "org.springframework.security.config.annotation.web.WebSecurityConfigurer", + getClass().getClassLoader()); + } + private static class LogFileCondition extends SpringBootCondition { @Override diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/NoSpringSecurityHealthMvcEndpointIntegrationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/NoSpringSecurityHealthMvcEndpointIntegrationTests.java new file mode 100644 index 0000000000..3a7e63e419 --- /dev/null +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/NoSpringSecurityHealthMvcEndpointIntegrationTests.java @@ -0,0 +1,95 @@ +/* + * 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 org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; +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.testutil.ClassPathExclusions; +import org.springframework.boot.testutil.FilteredClassPathRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.mock.web.MockServletContext; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; + +import static org.hamcrest.CoreMatchers.containsString; +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; +import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup; + +/** + * Integration tests for the health endpoint when Spring Security is not available. + * + * @author Andy Wilkinson + */ +@RunWith(FilteredClassPathRunner.class) +@ClassPathExclusions("spring-security-*.jar") +public class NoSpringSecurityHealthMvcEndpointIntegrationTests { + + private AnnotationConfigWebApplicationContext context; + + @After + public void closeContext() { + this.context.close(); + } + + @Test + public void healthDetailIsPresent() throws Exception { + this.context = new AnnotationConfigWebApplicationContext(); + this.context.setServletContext(new MockServletContext()); + this.context.register(TestConfiguration.class); + this.context.refresh(); + MockMvc mockMvc = webAppContextSetup(this.context).build(); + mockMvc.perform(get("/health")).andExpect(status().isOk()) + .andExpect(content().string(containsString("\"hello\":\"world\""))); + } + + @ImportAutoConfiguration({ JacksonAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, EndpointAutoConfiguration.class, + EndpointWebMvcAutoConfiguration.class, + ManagementServerPropertiesAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, WebMvcAutoConfiguration.class }) + @Configuration + static class TestConfiguration { + + @Bean + public HealthIndicator testHealthIndicator() { + return new HealthIndicator() { + + @Override + public Health health() { + return Health.up().withDetail("hello", "world").build(); + } + }; + } + + } + +}