From c6e08eb8833024e3616d1847c28b057ad4f80942 Mon Sep 17 00:00:00 2001 From: Rob Winch Date: Tue, 3 Nov 2015 10:10:07 -0600 Subject: [PATCH] Secure actuator when all endpoints are sensitive Previously if every actuator endpoint was marked as sensitive, then all endpoints were marked as permitted. This commit ensures that if all endpoints are marked as sensitive, then all the endpoints are secured. Fixes gh-4368 Closes gh-4383 --- ...anagementWebSecurityAutoConfiguration.java | 9 +++++-- ...mentWebSecurityAutoConfigurationTests.java | 24 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementWebSecurityAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementWebSecurityAutoConfiguration.java index be94fb0af97..01bcef9e906 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementWebSecurityAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/ManagementWebSecurityAutoConfiguration.java @@ -67,6 +67,7 @@ import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.AnyRequestMatcher; +import org.springframework.security.web.util.matcher.NegatedRequestMatcher; import org.springframework.security.web.util.matcher.OrRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.ObjectUtils; @@ -95,6 +96,9 @@ public class ManagementWebSecurityAutoConfiguration { private static final String[] NO_PATHS = new String[0]; + private static final RequestMatcher MATCH_NONE = new NegatedRequestMatcher( + AnyRequestMatcher.INSTANCE); + @Bean @ConditionalOnMissingBean({ IgnoredPathsWebSecurityConfigurerAdapter.class }) public IgnoredPathsWebSecurityConfigurerAdapter ignoredPathsWebSecurityConfigurerAdapter() { @@ -332,8 +336,7 @@ public class ManagementWebSecurityAutoConfiguration { for (String path : this.endpointPaths.getPaths(endpointHandlerMapping)) { matchers.add(new AntPathRequestMatcher(server.getPath(path))); } - return (matchers.isEmpty() ? AnyRequestMatcher.INSTANCE - : new OrRequestMatcher(matchers)); + return (matchers.isEmpty() ? MATCH_NONE : new OrRequestMatcher(matchers)); } } @@ -345,10 +348,12 @@ public class ManagementWebSecurityAutoConfiguration { ALL, NON_SENSITIVE { + @Override protected boolean isIncluded(MvcEndpoint endpoint) { return !endpoint.isSensitive(); } + }; public String[] getPaths(EndpointHandlerMapping endpointHandlerMapping) { diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ManagementWebSecurityAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ManagementWebSecurityAutoConfigurationTests.java index d0be9ccf388..33cd9ef78a5 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ManagementWebSecurityAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/ManagementWebSecurityAutoConfigurationTests.java @@ -61,6 +61,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** * Tests for {@link ManagementWebSecurityAutoConfiguration}. @@ -231,6 +234,27 @@ public class ManagementWebSecurityAutoConfigurationTests { .andExpect(springAuthenticateRealmHeader()); } + @Test + public void testMarkAllEndpointsSensitive() throws Exception { + // gh-4368 + this.context = new AnnotationConfigWebApplicationContext(); + this.context.setServletContext(new MockServletContext()); + this.context.register(WebConfiguration.class); + EnvironmentTestUtils.addEnvironment(this.context, "endpoints.sensitive:true"); + this.context.refresh(); + + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) // + .apply(springSecurity()) // + .build(); + + mockMvc // + .perform(get("/health")) // + .andExpect(status().isUnauthorized()); + mockMvc // + .perform(get("/info")) // + .andExpect(status().isUnauthorized()); + } + private ResultMatcher springAuthenticateRealmHeader() { return MockMvcResultMatchers.header().string("www-authenticate", Matchers.containsString("realm=\"Spring\""));