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 be94fb0af9..01bcef9e90 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 d0be9ccf38..33cd9ef78a 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\""));