Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,6 @@

package org.springframework.boot.actuate.autoconfigure.endpoint.expose;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.springframework.boot.actuate.endpoint.EndpointFilter;
import org.springframework.boot.actuate.endpoint.EndpointId;
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
Expand All @@ -32,6 +24,8 @@
import org.springframework.core.env.Environment;
import org.springframework.util.Assert;

import java.util.*;

/**
* {@link EndpointFilter} that will filter endpoints based on {@code include} and
* {@code exclude} patterns.
Expand Down Expand Up @@ -178,7 +172,7 @@ public enum DefaultIncludes {
/**
* The default set of include patterns used for web.
*/
WEB("info", "health");
WEB("health");

private final EndpointPatterns patterns;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration;
import org.springframework.boot.actuate.health.HealthEndpoint;
import org.springframework.boot.actuate.info.InfoEndpoint;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
Expand All @@ -38,12 +37,10 @@

/**
* {@link EnableAutoConfiguration Auto-configuration} for Spring Security when actuator is
* on the classpath. It allows unauthenticated access to the {@link HealthEndpoint} and
* {@link InfoEndpoint}. If the user specifies their own
* {@link org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
* WebSecurityConfigurerAdapter} or {@link SecurityFilterChain} bean, this will back-off
* completely and the user should specify all the bits that they want to configure as part
* of the custom security configuration.
* on the classpath. It allows unauthenticated access to the {@link HealthEndpoint}. If the user specifies their own
* {@link WebSecurityConfigurerAdapter} or {@link SecurityFilterChain} bean, this will
* back-off completely and the user should specify all the bits that they want to
* configure as part of the custom security configuration.
*
* @author Madhura Bhave
* @since 2.1.0
Expand All @@ -60,7 +57,7 @@ public class ManagementWebSecurityAutoConfiguration {
@Bean
SecurityFilterChain managementSecurityFilterChain(HttpSecurity http) throws Exception {
http.authorizeRequests((requests) -> {
requests.requestMatchers(EndpointRequest.to(HealthEndpoint.class, InfoEndpoint.class)).permitAll();
requests.requestMatchers(EndpointRequest.to(HealthEndpoint.class)).permitAll();
requests.anyRequest().authenticated();
});
http.formLogin(Customizer.withDefaults());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@
{
"name": "management.endpoints.web.exposure.include",
"defaultValue": [
"health",
"info"
"health"
]
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,7 @@

package org.springframework.boot.actuate.autoconfigure.security.reactive;

import java.net.URI;
import java.time.Duration;
import java.util.Collections;
import java.util.List;

import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;

import org.springframework.beans.BeansException;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
Expand Down Expand Up @@ -54,6 +47,12 @@
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebHandler;
import org.springframework.web.server.adapter.HttpWebHandlerAdapter;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.time.Duration;
import java.util.Collections;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
Expand All @@ -78,11 +77,6 @@ void permitAllForHealth() {
this.contextRunner.run((context) -> assertThat(getAuthenticateHeader(context, "/actuator/health")).isNull());
}

@Test
void permitAllForInfo() {
this.contextRunner.run((context) -> assertThat(getAuthenticateHeader(context, "/actuator/info")).isNull());
}

@Test
void securesEverythingElse() {
this.contextRunner.run((context) -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@

package org.springframework.boot.actuate.autoconfigure.security.servlet;

import java.io.IOException;

import org.junit.jupiter.api.Test;

import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.env.EnvironmentEndpointAutoConfiguration;
Expand Down Expand Up @@ -47,6 +44,8 @@
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.context.WebApplicationContext;

import java.io.IOException;

import static org.assertj.core.api.Assertions.assertThat;

/**
Expand All @@ -73,14 +72,6 @@ void permitAllForHealth() {
});
}

@Test
void permitAllForInfo() {
this.contextRunner.run((context) -> {
HttpStatus status = getResponseStatus(context, "/actuator/info");
assertThat(status).isEqualTo(HttpStatus.OK);
});
}

@Test
void securesEverythingElse() {
this.contextRunner.run((context) -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3960,10 +3960,10 @@ You can register multiple relying parties under the `spring.security.saml2.relyi

[[boot-features-security-actuator]]
=== Actuator Security
For security purposes, all actuators other than `/health` and `/info` are disabled by default.
For security purposes, all actuators other than `/health` are disabled by default.
The configprop:management.endpoints.web.exposure.include[] property can be used to enable the actuators.

If Spring Security is on the classpath and no other `WebSecurityConfigurerAdapter` or `SecurityFilterChain` bean is present, all actuators other than `/health` and `/info` are secured by Spring Boot auto-configuration.
If Spring Security is on the classpath and no other `WebSecurityConfigurerAdapter` or `SecurityFilterChain` bean is present, all actuators other than `/health` are secured by Spring Boot auto-configuration.
If you define a custom `WebSecurityConfigurerAdapter` or `SecurityFilterChain` bean, Spring Boot auto-configuration will back off and you will be in full control of actuator access rules.

NOTE: Before setting the `management.endpoints.web.exposure.include`, ensure that the exposed actuators do not contain sensitive information and/or are secured by placing them behind a firewall or by something like Spring Security.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ private UserDetails createUserDetails(String username, String password, String..
SecurityFilterChain configure(HttpSecurity http) throws Exception {
http.authorizeRequests((requests) -> {
requests.mvcMatchers("/actuator/beans").hasRole("BEANS");
requests.requestMatchers(EndpointRequest.to("health", "info")).permitAll();
requests.requestMatchers(EndpointRequest.to("health")).permitAll();
requests.requestMatchers(EndpointRequest.toAnyEndpoint().excluding(MappingsEndpoint.class))
.hasRole("ACTUATOR");
requests.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,16 +110,6 @@ void healthInsecureByDefault() {
assertThat(entity.getBody()).doesNotContain("\"hello\":\"1\"");
}

@Test
void infoInsecureByDefault() {
ResponseEntity<String> entity = this.restTemplate.getForEntity("/actuator/info", String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(entity.getBody()).contains("\"artifact\":\"spring-boot-smoke-test-actuator\"");
assertThat(entity.getBody()).contains("\"someKey\":\"someValue\"");
assertThat(entity.getBody()).contains("\"java\":{", "\"source\":\"1.8\"", "\"target\":\"1.8\"");
assertThat(entity.getBody()).contains("\"encoding\":{", "\"source\":\"UTF-8\"", "\"reporting\":\"UTF-8\"");
}

@Test
void testErrorPage() {
ResponseEntity<String> entity = this.restTemplate.withBasicAuth("user", "password").getForEntity("/foo",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public InMemoryUserDetailsManager inMemoryUserDetailsManager() {
SecurityFilterChain configure(HttpSecurity http) throws Exception {
// @formatter:off
http.authorizeRequests()
.requestMatchers(EndpointRequest.to("health", "info")).permitAll()
.requestMatchers(EndpointRequest.to("health")).permitAll()
.requestMatchers(EndpointRequest.toAnyEndpoint().excluding(MappingsEndpoint.class)).hasRole("ACTUATOR")
.antMatchers("/**").hasRole("USER")
.and()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ static class SecurityConfiguration {
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http.authorizeExchange((exchanges) -> {
exchanges.matchers(EndpointRequest.to("health", "info")).permitAll();
exchanges.matchers(EndpointRequest.to("health")).permitAll();
exchanges.matchers(EndpointRequest.toAnyEndpoint().excluding(MappingsEndpoint.class))
.hasRole("ACTUATOR");
exchanges.matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,9 @@ void userDefinedMappingsSecure() {
}

@Test
void healthAndInfoDoNotRequireAuthentication() {
void healthDoNotRequireAuthentication() {
this.webClient.get().uri("/actuator/health").accept(MediaType.APPLICATION_JSON).exchange().expectStatus()
.isOk();
this.webClient.get().uri("/actuator/info").accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk();
}

@Test
Expand Down Expand Up @@ -117,7 +116,7 @@ MapReactiveUserDetailsService userDetailsService() {
@Bean
SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception {
http.authorizeExchange((exchanges) -> {
exchanges.matchers(EndpointRequest.to("health", "info")).permitAll();
exchanges.matchers(EndpointRequest.to("health")).permitAll();
exchanges.matchers(EndpointRequest.toAnyEndpoint().excluding(MappingsEndpoint.class))
.hasRole("ACTUATOR");
exchanges.matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll();
Expand Down